JavaScript高级程序设计(ES5)
JavaScript简介
JavaScript简史
诞生于1995年,是一种客户端语言
JavaScript组成部分
核心(ECMAScript) ,它定义了以下规范
语法
类型
语句
关键字
保留字
操作符
对象
文档对象模型(DOM),它经历了以下变化
DOM1
DOM2
DOM3
浏览器对象模型(BOM)
小结
ECMAScript,由ECMA-262定义,提供核心语言功能
DOM文档对象模型,提供访问和操作网页内容的方法和接口
BOM浏览器对象模型,提供与浏览器交互的方法和接口
在HTML中使用JavaScript
script标签中间来写js代码
script标签的src属性用来引用外部js文件
script标签的属性
async,只对外部文件有效,表示异步执行
defer,只对外部文件有效,表示延迟执行
src,引用外部js文件
type,可不写,默认值是 text/javascript
小结
基本概念
语法
区分大小写——变量、函数和操作符都区分大小写
标识符
定义
标识符就是:变量、函数、属性的名字或者函数的参数
命名规则
首字母必须是字母、下划线或$符号
其他字符可以是字母、下划线、$符号或数字
识符中的字母也可以包含扩展的ASCII或 Unicode字母字符,但是不推荐这么做
格式
驼峰大小写格式,例如:sayHelloMessage
注释
单行注释 //
多行注释
/*
*/
严格模式
使用 use strict
在整个脚本中使用,则在文件第一行 使用
在方法上使用,则在方法体的第一样使用
语句
使用;代表一个语句结束,如果没有分号,则由解析器自动判断
一个语句往往使用 { }包裹起来,这也是推荐使用的方式,以便代码解构清晰
关键字和保留字
关键字
关键字不能用于标识符
关键字有哪些
保留字
保留字不能用作标识符
保留字有哪些
变量
变量定义
变量是松散类型的或者说是弱类型的,它可以保留任何类型的值
变量赋值
定义的时候直接赋值 —— var a = 1;
先定义,后赋值 —— var a; a = 1;
修改变量值的同时,修改变量的类型 —— var a = 1; a = 'hello'; 正确,但不推荐
同时给多个变量赋值(初始化不初始化均可),中间用逗号隔开 —— var a = 1,b=2,c=3;
数据类型
基本数据类型
Null
表示没有对象引用
Undefined
表示该变量未声明,或者声明了,但没有赋值
如果变量没有赋值,直接输出结果,则会报错。比如 alert( a );//直接报错
如果变量没有声明或者声明了但没有赋值,则使用 typeof 来判断,直接返回undefined
Number
在进行计算的时候,所有八进制和十六进制的数值最终都会被转换成十进制的数值。
浮点数值,会有精度问题,是因为IEEE754浮点计算的通病,比如:0.1+0.2 = 0.3000000000000004
数值范围
最大值:Number.MAX_VALUE
最小值:Number.MIN_VALUE
如果某次计算的值超过了JavaScript的数值范围,则该值自动转换为特殊的Infinity值,如果这个值是负值,则是 -Infinity(负无穷),如果这个值是正值,则是 Infinity(正无穷)
isFinite()函数用来检测数值是否位于最大值和最小值之间,例如 isFinite(100) //true
NaN
定义:NaN表示非数值,是一个特殊的值,NaN与任何值都不相等,与它自身也不相等,NaN==NaN //false
isNaN()函数用来判断不是数值,该函数接收到一个值时,会尝试将这个值转为数值,任何不能被转为数值的值都会返回true
isNaN(NaN);//true
isNaN(10); //false
isNaN(“10”);//false (可以被转换成数值10)
isNaN(“blue”);//true (不能转换成数值)
isNaN(true); //false (可以被转换成数值1)
尽管有点不可思议,但isNaN()确实也适用于对象。在给予对象调用isNaN()函数时,
会首先调用对象的valueOf()方法,然后确定该方法返回的值是否可以转换为数值。
如果不能,给予这个返回值在调用toString()方法,在测试返回值。而这个过程也是
ECMAScript中内置函数和操作符的一般执行流程。
数值转换,Number(),parseInt(),parseFloat()
Number()
(1)Number()函数的转换规则如下:
如果是Boolean值,true和false分别转为 1和0
如果是数字值,直接返回
如果是null值,则返回0
如果是undefined,则返回 NaN
如果是字符串,则遵循如下规则
如果字符串只包含数字(包括前面带正号和负号的情况),则将其转换为十进制。比如 “1”会变成1,“011”变成11, “+123”会变成 123
如果字符串中包含有效的浮点格式,则返回 浮点数值,比如 “0.12”则返回 0.12 “012.3” 变成 12.3
如果字符串包含有效的十六进制,则将其转换为相同大小的10进制返回。
如果字符串是空的,也即 “”,则返回 0
如果字符串中包含除了上述格式外的字符,则将其转换为NaN。比如 Number(“123a”)//结果NaN
如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。
parseInt()
(2)parseInt()函数更多的是看是否符合数值模式,它的转换规则如下:
如果是第一个字符是数字,则会继续解析第二个字符,直到解析完后面的字符,或者遇到了一个非数字字符。例如:parseInt(“123a”) //123
如果字符串前面有空格,则会忽略空格。比如 parseInt(“ 123”);//123,这个和Number()一致
浮点类型的字符串,会被转为 整数,即去掉小数点以及小数点后面的字符,这一点和Number()不同。
字符串是空的,则会返回NaN,这点和 Number不同
null也会转为NaN,这点和Number不同
如果第一个字符不是数字字符或正号或负号,则返回NaN,这与Number()表现一致
parseFloat
(3)parseFloat()函数
与parseInt很类似
第一个区别:对于第一个小数点有效,后面的小数点就无效了,比如 parseFloat(“3.12.2”);结果:3.12
第二个区别:parseFloat始终忽略前导的零。十六进制的字符串会始终为0 比如: parseFloat(“0xA”);//结果:0 parseFloat(“0908.5”);//结果908.5
第三点要注意:如果字符串包含一个可解析为整数的数,parseFloat会返回整数。
Boolean
Boolean类型的字面值,只有两个 true和false,区分大小写
可以通过Boolean()将其它类型的值转为 true或false,例如 Boolean("hello world");//true
在if条件语句中,会自动执行Boolean的转换,这个非常重要
String
定义:字符串可以用双引号或单引号表示,但是必须成对出现,比如var a='hello';或者 var a = "hello";
字符字面量
可以出现在字符串的任意位置,而且也将被作为一个字符来解析,例如:
var text = “This is the letter sigma:\\u03a3.” 其中的 \\u03a3只表示一个字符,它的length = 1,所以 text.length = 28
字符字面量
\\n 换行
\\t 制表
\\b 退格
\\r 回车
\\f 进纸
\\\\ 斜杠,其中前面的\\是转义符
\\’ 单引号
\\“ 双引号
字符串特点——不可变
ECMAScript中的字符串是不可变的,也就是说,字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量,例如:
var lang = “Java”
lang = lang + “Script”
以上示例中的变量lang开始时包含字符串“Java”.而第二行代码把lang的值重新定义为 “Java” 与 “Script”的组合,即“JavaScript”。实现这个操作的过程如下:首先创建一个能容纳10个字符的新字符串,然后把这个字符串中填充 “Java”和“Script”,最后一步是销毁原来的字符串“Java” 和 字符串 “Script”。
解决字符串拼接的性能问题
如何解决字符串拼接的性能问题:
方法是:使用数组保存,然后使用 join方法拼接即可。
如下:
var arr = [];
var oldStr1 = “Java”;
var oldStr2 = “Script”;
arr.push(oldStr1);
arr.push(oldStr2);
var finalStr = arr.join(“”);
转换为字符串
toString方法
var age = 11;
var ageString = age.toString(); //字符串 “11”
toString方法,还可以传入一个参数,用来指定要转换的进制数
例如 var num = 10; num.toString(); //无参数,与参数10同价,都是将数字转为10进制的字符串
num.toString(2); //“1010”,把10转为了2进制的字符串。
String()函数
String()函数,使用情况是,不知道要转换的是不是null或undefined.
String()能将任何类型的值转换为字符串
如果值是toString()方法,则调用该方法(没有参数)并返回相应的结果;
如果值是null,则返回 “null”
如果值是undefined,则返回 “undefined”
如下:
var value1 = 10;
var value2 = true;
var value3 = null;
var value4;
console.log(String(value1)); //“10” 等价于 value1+ “”;
console.log(String(value2)); // “true” 等价于 value2+ “”;
console.log(String(value3)); // “null” 等价于 value3+ “”;
console.log(String(value4)); // “undefined” 等价于 value4+ “”;
+"" 与String()函数功能相同
Symbol
es6新增的
引用数据类型
Object
定义
ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型名称来创建。而Object类型的创建方式如下:
var o = new Object();
var o= new Object;虽然没问题,但是推荐
Object的每个实例都具有下列属性和方法
(由于在ECMAScript中Object是所有对象的基础,因此所有对象也具有这些基本的属性和方法):
constructor:保存着用于创建当前对象的函数。对于前面的例子,构造函数(constructor)就是Object();
hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例如: o.hasOwnProperty(“name”))
isPrototypeOf(object):用于检查传入的对象是否是当前对象的原型。
propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举。
toLocalestring():返回对象的字符串表示,该字符串与执行环境的地区对应。
toString():返回对象的字符串表示
valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。
Array
Function
操作符
一元操作符
前置++和前置-- 变量的值在求值以前改变
var age = 10
++age;
console.log(age); //11
var age = 10;
var age1 = ++age +10;
console.log(age1); //21
后置++和后置-- 变量的值在求值以后改变
var age = 10
age++; 相当于 age = age+1;
console.log(age); //11
var age = 10;
var age1 = age++ +10; //注意,这里+10操作,因为age是求值之后改变所以 10+10 = 20;
console.log(age1); //20
注意理解:
var age = 10; age++; var age1 = ++age + 10; //age1 = 22;
var age = 10; age++; var age1 = age++ + 10; //age1 = 21;
注意理解:\nvar age = 10; age++; var age1 = ++age + 10; //age1 = 22;\nvar age = 10; age++; var age1 = age++ + 10; //age1 = 21;
所有这四个操作(前置++,前置--,后置++,后置--)对任何值都适用,也就是它们不仅适用于整数,还可以用字符串、布尔值、浮点数值和对象。在应用于不同的值时,++ --操作符遵循下列规则
在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减操作。
在应用于一个不包含有效数字字符的字符串时,将变量的值设置为NaN。
在应用于布尔值时候,false转为0,true转为1,再进行运算。
在应用于对象时候,先调用对象的valueOf()方法,然后对该值应用前面的规则,如果结果为NaN,则再调用toString()方法
var s1 = “2”;
var s2 = “z”;
var b = false;
var f = 1.1;
var o = {
valueOf:function(){
return -1;
}
}
s1++; //3
s2++; //NaN
b++; //1
f--; //0.10000000009(由于浮点舍入错误导致)
o--; //-2
加减操作符
对于数值,前面添加+号不会对结果产生任何影响。前面添加-号,则正数变负数,负数变正数
对于非数值应用时,false转0,true转1,对象会先调用valueOf和(或)toString方法
var s1 = “01”;
var s2 = “1.1”;
var s3 = “z”;
var b = false;
var f = 1.1;
var o = {
valueOf:function(){
return -1;
}
}
s1 = +s1; //1 如果使用 减号 s1 = -s1; //-1
s2 = +s2; //1.1 如果使用 减号 s2 = -s2; //-1.1
s3 = +s3; //NaN 如果使用 减号 s3 = -s3; //NaN
b = +b; //0 如果使用 减号 b = -b; //0
f = +f; //1.1 如果使用 减号 f = -f; //-1.1
o = +o; //-1 如果使用 减号 o = -0; //值变成了数值1
位操作符
布尔操作符
逻辑非 ! 它实际上是Boolean()的取反,双重逻辑非 !! 则效果等同于 Boolean()
alert(!false); //true
alert(!“blue”); //false
alert(!0); //true
alert(!NaN); //true
alert(!“”); //true
alert(!123456); //false
逻辑与 &&
true&&true => true
true&&false => false
false&&true => false
false&&false => false
有一个操作数不是布尔值的情况下,逻辑与操作就不一定返回布尔值;此时,它遵循下列操作:
如果第一个操作数是对象,则返回第二个操作数
如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象。
如果两个操作数都是对象,则返回第二个操作数
如果第一个操作数是null,则返回null
如果第一个操作数是undefined,则返回undefined
逻辑与属于短路操作
即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。对于逻辑与操作而言,如果第一个操作数是false,则无论第二个操作数是什么值,结果都不再可能是true了。如果第一个为true,则会继续对第二个求值。
逻辑或 ||
true||true => true
true||false => true
false||true => true
false||false => false
有一个操作数不是布尔值的情况下,逻辑或操作就不一定返回布尔值;此时,它遵循下列操作:
如果第一个操作数是对象,则返回第一个操作数
如果有一个操作数的求值结果为false,则返回第二个操作符
如果两个操作数都是对象,则返回第二个操作数
如果两个操作数都是null,则返回null
如果两个操作数都是NaN,则返回NaN
如果两个操作数都是undefined,则返回undefined、
逻辑或属于短路操作,即如果第一个操作数结果为true,就不会进行第二个操作数的求值了
我们可以利用逻辑或的这个行为,来为变量赋null或者undefined值。
alert(!123456);
var myOjbect = preferredObject || backupObject
这个例子中,变量myObject将被赋予等号后面两个值中的一个。变量preferredObject中包含优先赋给变量myObject的值,变量backupObject 负责在preferredObject中不包含有效值的情况下提供后备值。如果preferredObject的值不是null,那么它的值将被赋给myObject;如果是null,则将backupObject的值赋给myObject.
ECMAScript程序的赋值语句经常会使用这种模式。
乘性操作符 (乘法、除法、取余)
乘法
乘法操作符由一个星号(*)表示,用于计算两个数的乘积。例如 var result = 34*56;
在处理特殊的情况下,乘法操作符遵循下列特殊的规则:
如果操作数都是数值,执行常规的乘法计算,即两个正数或两个负数相乘的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果乘积超过了ECMAScript数值的表示范围,则返回Infinity或-Infinity;
如果有一个操作数是NaN,则结果是NaN
如果是Infinity与0相乘,则结果是NaN
如果是Infinity与非0数值相乘,则结果是Infinity或-Infinity,取决于符号操作数的符号
如果是Infinity与Infinity相乘,则结果是Infinity。
如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则。
除法
除法操作符由一个斜线符号( / )表示,执行第二个操作数除第一个操作数的计算。例如:var result = 66/11;
在处理特殊的情况下,除法操作符遵循下列特殊的规则:
如果操作数都是数值,执行常规的除法计算,即两个正数或两个负数相除的结果还是正数,而如果只有一个操作符由符号,那么结果就是负数。如果商超过了ECMAScript数值的表示范围,则返回Infinity或-Infinity;
如果有一个操作数是NaN,则结果是NaN;
如果是Infinity被Infinity除,则结果就是NaN
如果是零被零除,则结果是NaN
如果是非零的有限数被零除,则结果是Infinity或-Infinity,却绝育有符号操作数的符号;
如果是Infinity被任何非零数值除,则结果是Infinity或-Infinity,取决于有符号操作数的符号。
如果有一个操作数不是数值,则在后台调用Number() 将其转换为数值,然后再应用上面的规则。
取余
求模(余数)操作符由一个百分号(%)表示,例如: var result = 26%5;//等于1
求模操作符遵循如下特殊规则
如果操作数都是数值,则执行常规的除法计算,返回除得的余数
如果被除数是无穷大值而除数是有限大的数值,则结果是NaN
如果被除数是有限大的数值而除数是零,则结果是NaN
如果是Infinity被Infinity除,则结果是NaN
如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数
如果被除数是0,则结果是0
如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则。
加性操作符(加法、减法)
加法
加法操作符( + )的用法 例如: var result = 1 + 2;
如果两个操作符都是数值,执行常规的加法计算,然后根据下列规则返回结果:
如果有一个操作数是NaN,则结果是NaN;
如果是Infinity加Infinity,则结果是Infinity;
如果是-Infinity加-Infinity,则结果是-Infinity;
如果是Infinity加-Infinity,则结果是NaN;
如果是+0加+0,则结果是 +0
如果是-0加-0,则结果是 -0
如果是+0加-0,则解雇是 +0
如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来
如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后将这两个字符串拼接
如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法取得相应的字符串值,然后再应用前面关于两条关于字符串的规则,对于undefined和null,则分别调用String()函数并取得字符串 “undefined”和
“null”
var result1 = 5 + 5;//10
var result2 = 5 + “5”;//55
var num1 = 5;
var num2 = 10;
var message = “The sum of 5 and 10 is”+ num1+num2;//The sum of 5 and 10 is 510;
var message = “The sum of 5 and 10 is”+ (num1+num2);//The sum of 5 and 10 is 15;
减法
关系操作符 (>, <, >=, <=)
用法说明
小于,大于,小于等于,大于等于,这几个操作符用于对两个值进行比较,比较的规则和我们在数学上所学的是一样的,这几个操作符都返回布尔值,例如:var result1 = 5>3; //true var result2 = 5<3;//false
在ECMAScript中的其他操作符一样,当关系操作符的操作使用了非数值时,也要进行数据转换或完成某些奇怪的操作。以下就是相应的规则。
如果两个操作数都是数值,则执行数值比较。
如果两个操作数都是字符串,则比较两个字符串对应的字符编码值
如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较
如果一个操作数是对象,则调用这个对象的valueOf( )方法,用得到的结果按照前面的规则执行比较。如果对象没有valueOf()方法,则调用toString()方法,并用得到的结果根据前面的规则执行比较。
如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。
关于字符串的比较,有下面两种特殊情况需要注意
1.大写字母的字符编码全部小于小写字母的字符编码,所以会出现下面的情况:
var result = “Brick”< “alphabet” //true
上面之所以出现,是因为B的字符编码为66,而字母a的字符编码是97。如果要真正按字母表顺序比较字符串,就必须把两个操作数转换为相同的大小写形式(全部大写或全部小写),然后再执行比较,如下所示:
var result = “Brick”.toLowerCase()<“alphabet”.toLowerCase();//false
2.数字字符串的比较,同样比较的同样也是字符串首字母的 字符编码值:
var result = “23”<“3”; //true
但是
var result = “23”<3;//false
因为规则的第二条,此时会把 字符串 “23”自动转为 23再做比较。
相等操作符(==,!=,===,!===)
相等== 和 不相等!= 会自动强制类型转换后做比较
在转换不同的数据类型时,相等和不相等操作符遵循下列基本规则:
如果有一个操作符是布尔值,则在比较相等性之前先将其转换为数值——false转为0,true转为1
如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转为数值;
如果一个操作数是对象,另一个操组数不是,则调用对象的valueOf( )方法,用得到的基本数据类型进行比较
null 和 undefined 是相等的。
要比较相等性之前,不能把null和undefined转为其他任何值
如果有一个操作数是NaN,则相等操作符返回false,不相等操作符返回true。重要提示:即使两个操作数都是NaN,
相等操作符也返回false,因为按照规则NaN不等于NaN
如果两个操作数都是对象,则比较他们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true,否则,返回false.
全等===和不全等 !=== 直接做比较,不会类型转换
var result1=(“55”==55);//true,因为转换后相等
var result2=(“55”===55);//false,因为不同的数据类型不相等
null == undefined //true
null === undefined //false
条件操作符(3目表达式)
variable = boolean_expression ? true_value :false_value
赋值操作符
作用:只是简化赋值操作,不会带来任何性能提升
var num = 10;
num = num+10;//该行代码可以改为 num+=10;
每个主要算术操作符(以及个别的其他操作符)都有对应的复合赋值操作符。如下:
乘/赋值 (*=)
除/赋值 (/=)
模/赋值 (%=)
加/赋值 (+=)
减/赋值 (-=)
左移/赋值(<<=)
有符号右移/赋值 (>>=)
逗号操作符
逗号操作符多用于声明多个变量,比如 var num1=1,num2=2,num3=3;
逗号操作符用于赋值,在用于赋值时,逗号操作符总会返回表达式中的最后一项,如:var num=(5,1,0);//num结果0
语句
if语句
语法:
if(condition) statement1 else statement2 condition条件可以是任意表达式,而且这个表达式的求值不一定是布尔值,ECMAScript会自动调用Boolean()转换函数将这个表达式的结果转换为一个布尔值。如果condition的求值结果是true 则执行statement1,如果condition的求值结果是false,则执行statement2。
这两个语句既可以是一行代码,也可以代码块
if(i>25)
console.log(“1”); //单行语句可以不使用{}
else if(i=25){
alert();
console.log(); //多行语句,必须使用{}括起来。
}else{
alert();
}
但是我们推荐,无论单行语句还是多行语句,统统使用{}括起来,这样代码层次更分明。
if(i>25){
console.log(“1”);
}else if(i=25){
alert();
console.log(); }else{
alert();
}
do...while语句
定义:后测试循环语句
只有在循环体中的代码执行之后,才会测试出口条件。换句话说,对条件表达式求值之前,循环体中代码至少会被执行一次。
语法
do{
statement
}while(expression)
例如:
var i=0;
do{
i += 2;
console.log(i);
}while(i<10); //结果:2,4,6,8,10
while语句
定义:前测试循环语句
也就是说,在循环体内的代码被执行之前,就会对出口条件求值。
语法
while(expression)
例如:
var i = 0;
while (i<10){
i+=2;
}
for 语句
定义:前测试循环语句
它具有在执行循环体之前初始化变量和定义循环后要执行的代码的能力
语法:for(initialization;expression,post-loop-expression) statement
下面是一个示例:
var count = 10;
for(var i = 0;i < count;i++){
console.log(i);
}
以上代码定义了变量i的初始值是0 。只有当条件表达式(i<count)返回true的情况下才会进入for循环,因此也有可能不会执行循环体中的代码。如果执行了循环体中的代码,则一定会对循环后的表达式(i++)求值。这个for循环与
while循环跟那个相同:
var count = 0;
while (i<count){
console.log(i);
i++;
}
使用while做不到的,使用for循环同样做不到。也就是说,for循环只是把与循环有关的代码集中在了一个位置。有必要指出的是,在for循环的变量初始化表达式中,也可以不使用var关键字。该变量的初始化可以在外部执行,例如:
var count = 10;
var i;
for(i=0;i<count;i++){
count(i);
}
以上代码与在循环初始化表达式中声明变量的效果是一样的。由于ECMAScript中不存在块级作用域(第4章将进一步讨论这一点),因此在循环内部定义的变量也可以在外部访问到。例如:
var count = 10;
for(var i=0;i<count;i++){
var a = 100;
}
console.log(i); // 10
console.log(a); // 100
此外,for语句中的初始化表达式、控制表达式和循环后表达式都是可选的。将这三个表达式全部省略,就会创建一个无限循环,例如:
for(;;){ //无限循环
doSomething();
}
而只给出控制表达式实际上就把for循环转换成了while循环,例如:
var count = 10;
var i = 0;
for(;i<count;){
console.log(i);
i++;
}
for-in语句
定义: for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。
语法:for(property in expression) statement
例如:
for(var propName in window){
document.write(propName);
}