javascript学习总结一
1. 变量提升hoisting
变量提升的意思是在一个变量作用域里定义的变量的声明会被提升到作用域的顶部,这是变量只会被声明,不会被初始化复制,而是undefined。
代码如下:
function scopefunc() { console.log(variable1); /* console.log(variable2);*/ var variable1 = "I'm variable1"; console.log(variable1); }; window.onload = function () { scopefunc(); }
运行结果:
undefined
I'm variable1
被注释的那句代码会报错,证明没被定义的变量不是undefined而是直接报错。
针对变量的这个特性,在编写javascript代码时,应当遵循这样的风格:
在一个作用域的顶部使用一个 var 且定义所有的变量,可初始化或不初始化
如下:
1 function scropefunc() { 2 var variable1 = "I'm variable1", 3 variable2,func1; 4 console.log(variable1); 5 func1 = function () { 6 variable2 = "I'm variable2"; 7 console.log(variable2); 8 }; 9 }
ES6中使用的let 声明的变量不会发生变量提升,同时作用域是块作用域,表现就是当前花括号内。
函数声明:
(function() { log("first log"); function log(arg) { console.log(arg); } log("second log"); })();
函数声明也会被提到作用域的顶部,所以在声明之前使用函数也是可以的,比如上面的log函数。
ES5中函数声明不能在块中,但ES6中可以在块中声明函数,类似于使用了let所以不能提前使用,在具体使用时还是很容易令人迷惑的,所以避免在块中声明函数。
2. 变量作用域链
在上面一段代码中,func1函数里访问了variable2这个变量,但是这个变量只是在func1的外面的scopefunc函数内定义的,没有被func1所定义,那么func1是怎么找到的呢?
先介绍执行环境的概念,函数被调用时会产生一个新的执行环境,在JavaScipt引擎中,执行环境对象实现了执行环境这个概念。执行环境是可以嵌套的,并且内层的执行环境可以访问外层的执行环境,但外层的不能访问内层的执行环境。就像是一条链子,JavaScript在访问变量时,从当前执行环境开始查找,如果没有找到,向上一级执行环境中查找,直到顶级的执行环境(html中是window对象,nodejs是global),
3. 立即调用函数表达式 IIFE
立即调用函数表达式的全称是 Immediately Invoked Function Expression
这是一个js函数,在定义时就会执行,通常会用来防止污染全局变量,在模块模式中经常会用到
代码示例如下:
(function() { var private_Var = 7; console.log("this is inner IIFE"); })();
将这段代码靠到nodejs的命令行,回车就会输出this is inner IIFE,并且访问private_Var会出错。