51-JavaScript
1、简介
JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言。由ECMAScript(描述了该语言的语法和基本对象)、文档对象模型(DOM,描述处理网页内容的方法和接口)、 浏览器对象模型(BOM,描述与浏览器进行交互的方法和接口)组成。
2、存在形式
1:放在<head></head>中:
1 <head> 2 <script> 3 JS表达式 4 </script> 5 </head>
2:放在单独的JS文件中,然后引入:
1 <head> 2 <script src="JS文件名"></script> 3 </head>
3:放在<body></body>中:
1 <body> 2 <script> 3 JS表达式 4 </script> 5 </body>
4:因为用户请求script链接也需要时间,为了提高用户使用体验,一般将JS放置在body的最下面。
1 <body> 2 <div>.../<div> 3 ... 4 <script> 5 JS表达式 6 </script> 7 </body>
3、注释
单行注释 //
多行注释 /* ... */
4、变量
name = 'druid' // 声明一个全局变量
var name = 'druid' // 声明一个局部变量
5、数据类型
字符串:字符串是存储字符的变量。字符串可以是引号中的任意文本,您可以使用单引号或双引号。
数字:只有一种数字类型。数字可以带小数点,也可以不带。
布尔:布尔(逻辑)只能有两个值:true 或 false。(JavaScript这里为小写,Python中为大写)
数组:即Python中的列表。
对象:即Python中的字典。
undefined:undefined 这个值表示变量不含有值。
NULL:可以通过将变量的值设置为 null 来清空变量。
6、运算符
6.1 算术运算符
运算符 | 描述 | 例子 | 结果 |
---|---|---|---|
+ | 加 | x=y+2 | x=7 |
- | 减 | x=y-2 | x=3 |
* | 乘 | x=y*2 | x=10 |
/ | 除 | x=y/2 | x=2.5 |
% | 求余数 (保留整数) | x=y%2 | x=1 |
++ | 累加 | x=++y | x=6 |
-- | 递减 | x=--y | x=4 |
6.2 赋值运算符
运算符 | 例子 | 等价于 | 结果 |
---|---|---|---|
= | x=y | x=5 | |
+= | x+=y | x=x+y | x=15 |
-= | x-=y | x=x-y | x=5 |
*= | x*=y | x=x*y | x=50 |
/= | x/=y | x=x/y | x=2 |
%= | x%=y | x=x%y | x=0 |
6.3 比较运算符
运算符 | 描述 | 例子 |
---|---|---|
== | 等于 | x==8 为 false |
=== | 全等(值和类型) | x===5 为 true;x==="5" 为 false |
!= | 不等于 | x!=8 为 true |
> | 大于 | x>8 为 false |
< | 小于 | x<8 为 true |
>= | 大于或等于 | x>=8 为 false |
<= | 小于或等于 | x<=8 为 true |
注意!针对a>b>c这种写法,JavaScript会把a和b比较后的布尔值与c进行比较!
7、条件语句
7.1 if else语句
1 if(){ 2 3 } 4 else if 5 { 6 7 } 8 else{ 9 10 }
7.2 switch语句
工作原理:首先设置表达式 n(通常是一个变量)。随后表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行。请使用 break 来阻止代码自动地向下一个 case 运行。
1 switch(n) 2 { 3 case 1: 4 执行代码块 1 5 break; 6 case 2: 7 执行代码块 2 8 break; 9 default: 10 n 与 case 1 和 case 2 不同时执行的代码 11 }
8、 循环语句
8.1 for循环
1 li1 = [11, 22, 33, 44] 2 for (var i=0; i<li1.length; i++){ 3 document.write(i, "<br />") // 只会输出索引 4 document.write(li1[i], "<br />") // 输出索引对应的值 5 } //该循环方式不支持字典 6 7 /* i++和++i的区别 8 9 int i=1,a=0; 10 * i++ 先赋值再运算,例如 a=i++,先赋值a=i,后运算i=i+1,所以结果是a==1 11 * ++i 先运算再赋值,例如 a=++i,先运算i=i+1,后赋值a=i,所以结果是a==2 12 13 var i=1, a=0; 14 document.write("i++是先赋值再运算,所以结果:a=", a=i++, ",", "i=", i, "<br />"); 15 var i1=1, a1=0; 16 document.write("i++是先运算再赋值,所以结果:a1=",a1=++i1, ",", "i=", i1, "<br />"); 17 */
8.2 for/in循环
1 li1 = [11, 22, 33, 44] 2 for (var index in li1){ 3 document.write("<br />", index); // JS数组的for循环默认输出的是索引 4 } 5 for (var value in li1){ 6 document.write("<br />", li1[value]); // 通过索引才能取得值 7 } 8 dic1 = {"key1":"v1", "key2":"v2", "key3":"v3"} 9 for (var key in dic1){ 10 document.write("<br />", key); // JS字典的for循环默认输出的是key 11 } 12 for (var kv in dic1){ 13 document.write("<br />", dic1[kv]); // 通过key取出value 14 }
8.3 while循环
1 while (条件) 2 { 3 需要执行的代码 4 }
8.4 do/while循环
do/while 循环是 while 循环的变体。在检查条件是否为真之前,该循环会执行一次代码块。然后如果条件为真的话,就会重复这个循环。
1 do 2 { 3 需要执行的代码 4 } 5 while (条件);
9、函数
9.1 普通函数
1 function func(args){ 2 3 return arg+1 4 } 5 6 var res = func(arg); //调用函数并传参 7 console.log(res);
9.2 匿名函数
1 function(){ 2 3 }
应用举例:
1 setInterval(function(){ 2 console.log(123); 3 }, 5000)
9.3 自执行函数
1 (function(){ 2 console.log(123); 3 })()
10、序列化和反序列化
JSON.stringify() <=====> 序列化:将对象(内存中)转换为字符串。
JSON.parse() <=====> 反序列化:将字符串转换为对象类型(内存中)。
11、全局函数
函数 | 描述 |
---|---|
decodeURI() | 解码某个编码的 URI。 |
decodeURIComponent() | 解码一个编码的 URI 组件。 |
encodeURI() | 把字符串编码为 URI。 |
encodeURIComponent() | 把字符串编码为 URI 组件。 |
escape() | 对字符串进行编码。 |
eval() | 计算 JavaScript 字符串,并把它作为脚本代码来执行。 |
getClass() | 返回一个 JavaObject 的 JavaClass。 |
isFinite() | 检查某个值是否为有穷大的数。 |
isNaN() | 检查某个值是否是数字。 |
Number() | 把对象的值转换为数字。 |
parseFloat() | 解析一个字符串并返回一个浮点数。 |
parseInt() | 解析一个字符串并返回一个整数。 |
String() | 把对象的值转换为字符串。 |
unescape() | 对由 escape() 编码的字符串进行解码。 |
12、Date对象
Date 对象用于处理日期和时间。创建Date对象的语法:
var myDate=new Date() ---> Tue May 29 2018 14:18:05 GMT+0800 (中国标准时间)
然后可以对获取的Date对象进行操作,例如myDate.setXXX就是设置时间,myDate.getXXX获取小时、分钟等。
13、作用域
在其它语言(如Java、C#)中,是以代码块作为作用域的:
1 public void Func(){ 2 if(1==1){ 3 string name = 'C#'; 4 } 5 console.writeline(name); 6 } 7 8 Func() // 调用函数会报错。其c#中以代码块(即{})为单位,if结构体中的name变量和打印的name不属于一个代码块。
在Python中是以函数为作用域:
1 def func(): 2 if 1==1: 3 name = "Python" 4 print(name) 5 6 func() // 执行函数不会报错。
在JavaScript中也是以函数为作用域:
1 function func(){ 2 if(1==1){ 3 var name = "JavaScript"; 4 } 5 console.log(name); 6 } 7 8 func() //执行函数不会报错。
同时需要明白以下几点:
- 函数的作用域在函数未被调用之前已被创建。
1 name = "outside"; 2 function func(){ 3 console.log(name); 4 var name = "druid"; 5 console.log(name); 6 } 7 8 func(); // 输出结果 ---> 9 // undifined 10 // druid
- 函数的作用域存在作用域链,并且也是在被调用之前创建。
以下举例说明:
示例一:
1 name = "druid"; 2 function func(){ 3 var name = "eric"; 4 function inner(){ 5 var name = "inner"; 6 console.log(name); 7 } 8 inner(); 9 } 10 11 func(); 12 输出结果 ---> inner
示例二:
1 name = "druid"; 2 function func(){ 3 var name = "eric"; 4 function inner(){ 5 console.log(name); 6 } 7 8 return inner; 9 } 10 11 var res = func(); 12 res(); 13 输出结果 ---> eric
示例三:
1 name = "druid"; 2 function func(){ 3 var name = "eric"; 4 function inner(){ 5 console.log(name); 6 } 7 var name = "tony"; 8 return inner; 9 } 10 11 var res = func(); 12 13 res(); 14 输出结果 ---> tony
- 函数内局部变量会提前声明(未给变量赋值则系统自动赋值为undefined)。
示例:在解释的过程中,解释器会找到所有的局部变量,执行var name,并且给name赋值为undefined
1 function func(){ 2 console.log(name); 3 var name = "druid"; 4 } 5 6 func(); 7 输出结果 ---> undefined
14、活动对象
1 function f1(age){ 2 console.log(age); 3 var age = 27; 4 console.log(age); 5 function age(){}; 6 console.log(age); 7 } 8 9 f1(3); 10 /* 执行结果为: 11 ƒ age(){} 12 27 13 27 14 15 为什么是这样?因为JS中活动对象导致的(active object)。什么是活动对象(AO)? 16 未进入执行阶段之前,变量对象中的属性都不能访问!但是进入执行阶段之后,变量对象转变为了活动对象,里面的属性都能被访问了,然后开始进行执行阶段的操作。所以活动对象实际就是变量对象在真正执行时的另一种形式。 17 在分析活动对象的时候从以下三个方面去分析: 18 1. 形式参数 19 2. 局部变量 20 3. 函数声明表达式(优先级比较高) 21 分析如下: 22 1. 从形式参数上分析 23 AO.age = undefined ---> AO.age = 3 24 2. 从局部变量上分析 25 AO.age = undefined(词法分析阶段,程序不会执行。如果有age,不做任何改变,因此为undefined) 26 3. 从函数声明表达式上分析(优先级比较高) 27 AO.age = age(){} 28 29 从分析来看,因为函数表达式优先级最高,因此函数体中第一句console.log(age)输出ƒ age(){};然后第二行声明 var age = 27 ,因此第三行console.log(age)的结果为27;第四行function age(){}没有被调用,因此没有执行;最后的console.log(age)结果仍为27。 30 */
15、面向对象
1 function Foo(n){ 2 this.name = n; 3 this.sayName = function(){ 4 console.log(this.name); 5 } 6 } 7 8 var obj1 = new Foo("druid"); // 实例化 9 10 /* 11 a. this代指对象本身(与python类的self类似) 12 b. 创建对象时,写法是new 类名(参数) 13 var obj1 = new Foo("druid"); 14 相当于 ---> Foo(obj1, "druid") ---> obj1.name = druid 15 obj1.sayName = function(){ 16 console.log(obj1.name); 17 } 18 19 执行obj1的输出结果为---> Foo {name: "druid", sayName: ƒ} 20 执行obj1.name的输出结果为 ---> druid 21 执行obj1.sayName()的输出结果为 ---> druid 22 */
上述的写法(将方法写在类中)会浪费内存,因此可以用原型来解决:
1 function Foo(n){ 2 this.name = n; 3 } 4 5 Foo.prototype = { 6 "sayName": function(){ 7 console.log(this.name) 8 } 9 } //Foo类的原型 10 11 var obj1 = new Foo("druid"); 12 13 /* 14 var obj1 = new Foo("druid"); 15 相当于 ---> Foo(obj1, "druid") ---> obj1.name = druid 16 obj1.sayName = function(){ 17 console.log(obj1.name); 18 } 19 20 执行obj1的输出结果为---> Foo {name: "druid", sayName: ƒ} 21 执行obj1.name的输出结果为---> druid 22 执行obj1.sayName()的输出结果为---> druid 23 */