<前端技术>JavaScript

时间:Aug. 6, 2017 分类:

目录:

浏览器内置了JavaScript的语言解释器,在浏览器上按照JavaScript(以下简称js)规则编写的代码浏览器可以做出相应的处理。

js的存在形式

<!-- 方式一 -->
<script type"text/javascript" src="JS文件"></script>

<!-- 方式二 -->
<script type"text/javascript">
    Js代码内容
</script>

js的代码存放位置

  • HTML的head中
  • HTML的body代码块底部(推荐)

原因是html是从上到下的执行,如果head中加在js代码耗时严重,就会导致用户长时间无法看到页面,而如果放置在body代码块底部,那么及时js代码耗时严重,也不会影响用户看到的效果,只是js的特效显示的慢一些

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="https://www.gstatic.com/og/_/js/k=og.og2.en_US.iF4jnkQuaf0.O/rt=j/t=zcms/m=def/exm=in,fot/d=1/ed=1/rs=AA2YrTv5-POC4Ks9GtGRdY2ywUWisqz7-Q"></script>
<script>
    alert('123');
</script>
</body>
</html>

全局变量和局部变量

<script type="text/javascript">

    // 全局变量
    name = 'seven';

    function func(){
        // 局部变量
        var name = 18;

        // 全局变量
        gender = "男"
    }
    console.log(name)
</script>

看一下显示的name为全局变量name

这个是怎么打开的呢,我这个是谷歌浏览器的更多工具-->开发者工具中的console,默认可以ctrl+shift+i来打开

如果把console.log(name)写入func方法,显示的name为局部变量name

<script type="text/javascript">

    // 全局变量
    name = 'seven';

    function func(){
        // 局部变量
        var name = 18;

        // 全局变量
        gender = "男"
        console.log(name)
    }
    func();

</script>

展示效果

如果把console.log(name)写在局部变量之前,就会出现name未定义的情况

<script type="text/javascript">

    // 全局变量
    name = 'seven';

    function func(){

        console.log(name)

        // 局部变量
        var name = 18;

        // 全局变量
        gender = "男"

    }
    func();

</script>

展示效果

可以看到如果先输出就会出现未定义的情况

这样的话可以的

<script type="text/javascript">

    // 全局变量
    name = 'seven';

    function func(){



        // 局部变量
        var name;

        console.log(name)        

        // 全局变量
        gender = "男"

    }
    func();

</script>

展示效果

注释方式

  • 单行 //
  • 多行 /* */

数据类型

JavaScript的数据类型分为原始类型和对象类型

  • 原始类型 数字,字符串,布尔值

  • 对象类型 数组,字典

特别的是,数字,布尔值,null,undefindend和字符串是不可变的。

特殊介绍

  • null是JavaScript语言的关键字,它表示一个特殊值,常用来描述“空值”。
  • undefined是一个特殊值,表示变量未定义。

数字

JavaScript中是不区分整数型和浮点型,JavaScript中所有的数据均采用浮点数值来进行表示

转换的方法是

  • parseInt 将某值转化成数字,不成功则为NaN
  • parseFloat 将某值转化成浮点数,不成功则为NaN

而对应的特殊值

  • NaN为非数字,可以通过isNaN(num)来判断
  • Infinity为无穷大,可以通过isFinite(num)来判断

以下操作都在console中实现

>n1 = 123
<123
>n2 = 123.456
<123.456
>n3 = 'why123'
<"why123"
>parseInt(n1)
<123
>parseInt(n2)
<123
>parseInt(n3)
<NaN
>n4=parseInt(n3)
<NaN

可以看到n3转化失败了,返回了NaN

inNaN

>isNaN(n4)
<true
>isNaN(n2)
<false

isNaN() False => 数字 True => 非数字

Infinity

>a = Infinity
<Infinity
>isFinite(a)
<false

isFinite() False => 有限数字 True => 无穷大

判断类型

>n1 = '123'
<"123"
>typeof n1
<"string"
>n1 = 123
<123
>typeof n1
<"number"

类型转化

>n1.toString()
<"123"

数字的方法

方法 描述
Number 对数字的支持
Number.MAX_VALUE 最大数值
Number.MIN_VALUE 最小数值
Number.NaN 特殊的非数字值
Number.NEGATIVE_INFINITY 负无穷大
Number.POSITIVE_INFINITY 正无穷大
Number.toExponential() 用指数计数法格式化数字
Number.toFixed() 采用定点计数法格式化数字
Number.toLocaleString( ) 把数字转换成本地格式的字符串
Number.toPrecision( ) 格式化数字的有效位
Number.toString( ) 将—个数字转换成字符串
Number.valueOf( ) 返回原始数值

更多的可以参考连接

Js实现跑马灯

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="i1" style="background-color:red; color: white; font-size: 54px; text-align:center; ">精通各大语言的HelloWorld</div>
<script type="text/javascript">
    setInterval(function () {
        dl = document.getElementById('i1');
        dl_text = dl.innerText;
        console.log(typeof dl_text);
        first_str = dl_text[0];
        sub_str = dl_text.slice(1,dl_text.length);
        new_str = sub_str + first_str;
        dl.innerText = new_str;
    },500);

</script>

</body>
</html>

实现方式 - 通过document.getElementById获取到id为i1的代码,innerText获取到内容,dl_text[0]获取内容的第一个字符和dl_text.slice(1,dl_text.length)第二个字符到最后一个字符,将第一个字符防止到末尾,然后将内容换为以下内容。

展示效果

字符串

在JavaScript中,字符串为字符组成的数组,可以使用数组的方式进行操作,字符串本身未提供修改字符串的方法。

字符串的索引和拼接

>a = "why"
<"why"
>a[0]
<"w"
>a.charAt(0)
<"w"
>b = "mabiao"
<"mabiao"
>ret = a.concat(b)
<"whymabiao"
>ret
<"whymabiao"
>a
<"why"
>ret = a.concat(b, "123")
<"whymabiao123"
>ret = a.concat(b, "123", "iii")
<"whymabiao123iii"

可以通过索引获取值,可以通过concat进行合并字符串操作

字符串获取索引

>a = "whywhywhy"
<"whywhywhy"
>a.indexOf("hy")
<1
>a.indexOf("hy",1)
<1
>a.indexOf("hy",2)
<4
>a.indexOf("hy",3)
<4
>a.indexOf("hy",4)
<4
>a.indexOf("hy",5)
<7
>a.lastIndexOf('hy')
<7

通过indexOf获取索引,一个参数的时候只获取第一个索引的位置,而加入参数后,可以看到第二个参数是获取当前索引位置及其以后位置的第一个匹配的索引,lastIndexOf是获取最后一个的索引。

字符串分割

>a = "whywhywhy"
<"whywhywhy"
>a.split('hy')
<["w", "w", "w", ""]
>a.split('h')
<["w", "yw", "yw", "y"]
>a.split('h', 1)
<["w"]
>a.split('h', 2)
<["w", "yw"]
>a.split('h', 3)
<["w", "yw", "yw"]
>a.split('h', 4)
<["w", "yw", "yw", "y"]

可以看到如果正好分割的话,会有一个空字符串,第二个参数是指显示几个,而不是分为几段

字符串正则分割

>a = "why6wanghongyu8wwwww"
<"why6wanghongyu8wwwww"
>a.split('6')
<["why", "wanghongyu8wwwww"]
>a.split(/(\d)/)
<["why", "6", "wanghongyu", "8", "wwwww"]
>a.split(/\d/)
<["why", "wanghongyu", "wwwww"]
>a.split(/(\d)w/)
<["why", "6", "anghongyu", "8", "wwww"]

可以看到通过()包裹的可以进行显示

字符串正则匹配

>a = "why6wanghongyu8wwwww"
<"why6wanghongyu8wwwww"
>a.search("hy")
<1
>a.search("why")
<0
>a.match(/why/)
<["why"]
>a.search(/hy/)
<1

可以看到search到的是索引,而match到的是匹配的字串,加g可以查找全部

字符串替换

>a = "why6wanghongyu8wwwww"
<"why6wanghongyu8wwwww"
>a.replace(/\d/,"&")
<"why&wanghongyu8wwwww"
>a.replace(/\d/g,"&")
<"why&wanghongyu&wwwww"
>a.replace(/(\d)\w+(\d)/g)
<"whyundefinedwwwww"
>a.replace(/(\d)\w+(\d)/g, "$1$2")
<"why68wwwww"
>a.replace(/(\d)\w+(\d)/g, "$2$1")
<"why86wwwww"
>a.replace(/(\d)\w+(\d)/g, "$2hhhh$1")
<"why8hhhh6wwwww"
>a.replace(/(\d)\w+(\d)/g, "$2$$$1")
<"why8$6wwwww"
>a.replace(/\d/, "$`")
<"whywhywanghongyu8wwwww"
>a.replace(/\d/g, "$`")
<"whywhywanghongyuwhy6wanghongyuwwwww"
  • 加g:所有正则匹配的内容进行替换,如果不加则只替换第一个
  • 加i:不区分大小写
  • 加m:多行匹配
  • $数字:匹配到的第n组的内容
  • $&:当前匹配内容
  • $$:符号$
  • $`:位于匹配子串左侧的文本
  • $':位于匹配子串右侧的文本

字符串长度

a.length
20
  • trim()移除空白
  • toLowerCase()小写
  • toUpperCase()大写

布尔值

  • ==:比较值相等
  • !=:不等于
  • ===:比较值和类型相等
  • !===:不等于
  • ||:或
  • &&:且
>a = 123
<123
>b = 123
<123
>a == b
<true
>a === b
<true
>a = "123"
<"123"
>b = 123
<123
>a == b
<true
>a === b
<false

两个相同数字之间,==和===都为true,两个相同的数字和字符串之间,==为true,===为false

数组

JavaScript中的数组类似Python中列表

>a = [11, 22, 33, 44]
<[11, 22, 33, 44]
>a.length
<4
>a.push(55)
<5
>a
<[11, 22, 33, 44, 55]
>ret = a.pop()
<55
>ret
<55
>a
<[11, 22, 33, 44]

可以看到length,push,pop都对应python中的操作

>a.splice(1, 0, "why")
<[]
>a
<[11, "why", 22, 33, 44]
>a.splice(1, 0, "wwww","hhh")
<[]
>a
<[11, "wwww", "hhh", "why", 22, 33, 44]
>a.splice(1,2)
<["wwww", "hhh"]
>a
<[11, "why", 22, 33, 44]
>a.splice(1,2)
<["why", 22]
>a
<[11, 33, 44]
>a.reverse
<reverse() { [native code] }
>a.reverse()
<[44, 33, 11]
>a.join("_")
<"44_33_11"
  • splice(n,0,val):指定位置插入元素
  • splice(n,m,val):指定位置替换m个元素
  • splice(n,m):指定位置删除m个元素
  • splice(start, deleteCount, value, ...)
  • reverse()反转
  • join()构建字符串
  • sort()排序
  • concat()连接数组
  • unshift()首部插入元素
  • shift()尾部插入元素

序列化

JavaScript通过json格式进行序列化和反序列化

使用的方法

  • JSON.stringify(obj)序列化
  • JSON.parse(str)反序列化
>a = {k1:123,k2:456}
<Object {k1: 123, k2: 456}
>a['k1']
<123
>b = [11, 22, 33, 44]
<[11, 22, 33, 44]
>JSON.stringify(b)
<"[11,22,33,44]"
>s = JSON.stringify(b)
<"[11,22,33,44]"
>JSON.parse(s)
<[11, 22, 33, 44]

eval

eval在JavaScript中是Python中exec和eval的合集

>eval('for(var i=1;i<10;i++){console.log(i)}')
VM1071:1 1
VM1071:1 2
VM1071:1 3
VM1071:1 4
VM1071:1 5
VM1071:1 6
VM1071:1 7
VM1071:1 8
VM1071:1 9
<undefined

正则补充

test(string)

>var ret = /^1[3|5|8]\d{9}$/;
<undefined
>ret.test('13552493019')
<true
>ret.test('17355688745')
<false

定义规则,通过test进行测试

exec(string)

>reg = /\d+/
</\d+/
>reg.exec('fgh3hjui7saf')
<["3"]
>reg.exec('fgh3hjui7saf')
<["3"]

获取匹配到的内容,如果未匹配到,则为null

>reg = /\d+/g
</\d+/g
>reg.exec('fgh3hjui7saf')
<["3"]
>reg.exec('fgh3hjui7saf')
<["7"]

时间

>obj = new Date()
<Wed Aug 02 2017 16:54:58 GMT+0800 (中国标准时间)
>obj.getDate()
<2
>obj.getSeconds()
<58
>obj.setFullYear(2018)
<1533200098383
>obj
<Thu Aug 02 2018 16:54:58 GMT+0800 (中国标准时间)
>obj.getHours()
<16
>obj.getUTCHours()
<8

http://www.shouce.ren/api/javascript/main.html

条件语句

在JavaScrpit中支持两种条件语句,分别是if和switch

if

if 条件:
    ...
elif xxx:
    ...
else:
    ...

if(条件){
    ...
}else if(条件){
    ...
}else{
    ...
}

switch

name = 123;
switch(name){
    case "1":
        console.log(1);
        break
    case "123":
        console.log(123);
        break
    default:
        console.log('default')
}

注意""

示例

function f1(name){
switch(name){
    case 1:
        console.log(1);
        break
    case 123:
        console.log(123);
        break
    default:
        console.log('default')
    }
}
f1(1);
f1(12);
f1(123);

执行的console为

1
default
123

循环语句

在JavaScript中支持三种循环方式

方式一

li = [11, 22, 33, 44]
for(var item in li){
    console.log(item);
    console.log(li[item]);
}

执行结果

0
11
1
22
2
33
3
44

可以看到for循环循环的是索引

也可以循环字典类的东西

dic = {"k1":123, "k2":456}
for(var item in dic){
    console.log(item);
}

执行结果

k1
k2

可以看到循环的也为key

方式二

for(var i=0; i<10; i++){
    console.log(i);
}

执行结果

0
1
2
3
4
5
6
7
8
9

下面的也同理

for(var i=10; i>0; i--){
    console.log(i);
}

如果实现上述方式就通过length来实现

var li = [11, 22, 33, 44];

for(var i=0;i<li.length;i++){
    console.log(i);
    console.log(li[i]);
}

方式三

while (true){
    break;
    continue;
}

while的方式,通过break和continue进行控制。

异常处理

try {
    //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行
}
catch (e) {
    // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。
    //e是一个局部变量,用来指向Error对象或者其他抛出的对象
}
finally {
     //无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。
}

函数

JavaScript的函数分为三类,普通函数,匿名函数和自执行函数。

普通函数

function f1(arg) {
    console.log(123);
}

匿名函数

var func = function(arg){
        return "why";
    }

自执行函数

(function(arg){
    console.log(arg);
})('why');

参数问题

在JavaScript中的函数参数,实际参数的个数可能小于形参个数,统一都被封装到了argumens中

function f1(a, b, c) {
    console.log(argumens);
    console.log(a, b, c);
}
f1(1, 2, 3, 4)

执行结果

作用域

i = 123;
function f1() {
    function f2() {
        var name = 'why';
        console.log(i);
    }
    f2();
}
f1();

执行结果

123

可以看到f2中没有,找到f1,进而找到全局变量,不信你可以在f1中定义一个i

i = 123;
function f1() {
    i = 456
    function f2() {
        var name = 'why';
        console.log(i);
    }
    f2();
}
f1();

执行结果

456

在f2中也写一个

i = 123;
function f1() {
    i = 456;
    function f2() {
        i = 789;
        var name = 'why';
        console.log(i);
    }
    f2();
}
f1();

执行结果

789

通过匿名函数进行调用

name = 'why';
function f1() {
    var name = 'wanghongyu';
    function f2() {
        alert(name);
    }
    return f2
}
var ret = f1();
ret();

可以弹出的窗体里为wanghongyu

由此可见JavaScript中每个函数都有自己的作用域,当出现函数嵌套,就出现了作用域链,当内层函数使用变量会从作用域链一层一层

闭包

笔者不大理解。

面向对象

function Foo(name, age) {
    this.Name = name;
    this.Age = age;
    this.Func = function () {
        return this.Name + this.Age;
    }
}

obj1 = new Foo('why',24);
obj2 = new Foo('wanghongyu',24);
console.log(obj1.Name);
console.log(obj2.Name);
ret = obj2.Func();
console.log(ret);
  • Foo为构造函数
  • this代指对象
  • 创建新的对象的时候使用new来创建
function Foo(name, age) {
    this.Name = name;
    this.Age = age;
    }

Foo.prototype = {
    Func: function () {
        return this.Name + this.Age
    }
};

obj1 = new Foo('why', 24);
obj1.Func();