JavaScript 笔记
变量提升(hoisting):JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行运行。所以所有变量的声明都会被提升到头部,这就是变量提升,但赋值不会跟着提升。
标签(label):标签相当于定位符,用于跳转到程序的任意位置,通常和break、continue配合使用。
下面代码break将直接跳出双层循环,如果只使用break将仅跳出内层循环。
top: for (var i = 0; i < 3; i++){ for (var j = 0; j < 3; j++){ if (i === 1 && j === 1) break top; console.log('i=' + i + ', j=' + j); } } // i=0, j=0 // i=0, j=1 // i=0, j=2 // i=1, j=0
break也可用于跳出代码块
foo: { console.log(1); break foo; console.log('本行不会输出'); } console.log(2); // 1 // 2
continue将使下面代码直接进入下一轮外层循环,而仅使用continue将进入下一轮内层循环
top: for (var i = 0; i < 3; i++){ for (var j = 0; j < 3; j++){ if (i === 1 && j === 1) continue top; console.log('i=' + i + ', j=' + j); } } // i=0, j=0 // i=0, j=1 // i=0, j=2 // i=1, j=0 // i=2, j=0 // i=2, j=1 // i=2, j=2
typeof:typeof可以返回一个值的数据类型。
typeof 123 // "number" typeof '123' // "string" typeof false // "boolean" function f() {} typeof f // "function" typeof {} // "object" typeof [] // "object" typeof NaN // "number"
typeof null // "object" typeof undefined // "undefined"
因为 typeof undefined == "undefined" ,所以也可以用来检查一个变量有没有被声明
// 错误的写法,使用一个为声明的变量将会报错 if (v) { // ... } // ReferenceError: v is not defined // 正确的写法 if (typeof v === "undefined") { // ... }
null
的类型是object
,这是由于历史原因造成的。1995年的 JavaScript 语言第一版,只设计了五种数据类型(对象、整数、浮点数、字符串和布尔值),没考虑null
,只把它当作object
的一种特殊值。后 来null
独立出来,作为一种单独的数据类型,为了兼容以前的代码,typeof null
返回object
就没法改变了。
{ foo: 123 }行首是一个大括号,这是一个代码块不是对象:如果想要解释为对象,加一个括号({ foo: 123 }),因为括号里面只能是表达式,所以这样只能解释为对象。
对象属性的可枚举和不可枚举:属性是否可枚举可以用Object.propertyIsEnumerable(propName)判断,但要注意的是如果判断原型对象上的属性始终返回false。可以使用Object.defineProperty(obj, propName, {})来定义属性是否可枚举,第三个参数填{enumerable: false}表示不可枚举,即不可被for...in遍历到。引入enumerable的目的是可以让一些属性规避掉for...in循环,比如toString()方法和数组的length属性就是通过这种方法规避的。
for...in循环:遍历对象和原型链中对象的所有可枚举的属性。
Object.keys():返回对象自身所有可枚举属性的属性名组成的数组,不会列出原型链中对象的属性,而for...in循环可以遍历包括原型链中的属性。
函数名的提升:JavaScript引擎将函数名视为变量名,所以函数名会提升。但要注意使用function命令声明的函数和赋值语句形式声明的函数
// 下面调用不会报错 f(); function f() {}
// 下面调用会报错 f(); var f = function (){}; // TypeError: undefined is not a function // 上面的代码等同于下面的形式 var f; f(); f = function () {};