说明
重学前端是程劭非(winter)在极客时间开的一个专栏,在此主要整理我的学习笔记。如有侵权,请联系我,谢谢。
执行上下文在不同版本的概念
var声明与赋值
var声明能够穿透if、for等语句
立即执行函数,通过声明一个函数,并且立即执行,来构建一个新的域。来控制var的范围
语法规定function关键字开头是函数声明,为了变成函数表达式,可以在前面加东西。
- 加括号
(function(){
var a;
//code
}());
(function(){
var a;
//code
})();
加括号有个缺点,就是如果在最后不加分号,括号会被解释为上一行代码最末的函数调用。因此有些做法是
- 加前面加分号
;(function(){
var a;
//code
}())
;(function(){
var a;
//code
})()
- void 关键字法
void function(){
var a;
//code
}();
void表示忽略后面表达式的返回值,变成undefined,在使用立即执行函数时,我们并不关系函数的返回值
在with用法里, var 的特性会导致声明的变量和被赋值的变量是两个 b
var b;
void function(){
var env = {b:1};
b = 2;
console.log("In function b:", b); // 2
with(env) {
var b = 3;
console.log("In with b:", b); //3
}
}();
console.log("Global b:", b); // undefined
在with声明的b作用到了外部function的环境上,对两个域(with和function)产生了作用,这是用with的弊端。
这里我修改一下,看看不同的写法,b的值有什么不同
var b;
void function(){
var env = {b:1};
b = 2;
console.log("In function b:", b); //2
var b = 3;
}();
console.log("Global b:", b); //undefined
这个时候b还是不同,因为在立即执行函数里用了var关键字声明了b,所有b=2赋值的是该作用域的b,不是全局作用域的b。
var b;
void function(){
var env = {b:1};
b = 2;
console.log("In function b:", b); //2
}();
console.log("Global b:", b); //2
这个时候b是同一个b。这个是作用域链在查找变量的时候,如果在内部的作用域找到这个变量的,就会停止查找,如果找不到,会去外层作用域继续查找,直到找到为止。
let
let是es6引入的新的变量声明模式,为了实现let,es6在运行时引入了块级作用域
以下语句会产生let使用的作用域:
- for
- if
- switch
- try/catch/finally
Realm
新概念。
Realm中包含一组完整的内置对象,而且是复制的关系
var iframe = document.createElement('iframe')
document.documentElement.appendChild(iframe)
iframe.src="javascript:var b = {};"
var b1 = iframe.contentWindow.b;
var b2 = {};
console.log(typeof b1, typeof b2); //object object
console.log(b1 instanceof Object, b2 instanceof Object); //false true
b1和b2是由同样的代码在不同的Realm中执行,在用instanceof是会有不同的行为。