一、this
1.this是什么?
this是JavaScript中自动定义的特殊标识符关键字,是在函数被调用时建立的一个绑定,它的指向由函数被调用的调用点来决定
2.this的判定?
- 如果是通过 new 调用的,this是新构建的对象。
- 如果是通过 call 或 apply(或 bind)调用的,this是指定的对象。
- 如果是通过持有调用的环境对象调用的,this是那个环境对象。
默认情况下:- strict mode 下,this是undefined, 否则是全局对象
- 非strict mode 下,this是全局对象(浏览器环境的window或Node环境的global)
二、变量提升
变量提升是Javascript中执行上下文的工作方式。你可以看成声明被移到作用域顶部。
讨论这个问题前,为免歧义,我们约定变量提升的三个阶段:
- 声明:打破变量原有的声明/初始化 位置,提升到最前面
- 初始化:第1次赋值
- 赋值
1. ES5的变量提升
num = 1;
// 其他代码
var num;
/* 没有报错,只要声明了num */
上面是一个变量提升简单经典的例子,和下面这段代码等价:
var num;
num = 1;
// 其他代码
这就是为什么没有错误,还能正常使用的原因。注意:这里 提升声明,也提升初始化(undefined),假设例子改为:
var a = 1;
console.log(a, b); // '1 undefined'
var b = 2;
等价代码(实际步骤):
var a = 1; // 声明并初始化 a为1
var b; // 声明 b ,初始化 b为undefined
console.log(a, b); // 1 undefined
b = 2; // b被赋值为2 (这里不叫初始化)
var 的 声明 和 初始化 被提升了。(但是 赋值 没有被提升)
变量提升还体现在函数上:
// 注意:仅仅用于学习,不提倡先call再写声明
sayHello("Mark"); // 你好,Mark
function sayHello(name) {
console.log("你好," + name);
}
上面的代码没有报错。
function 的 声明、初始化 以及 赋值 都被提升了。
2. ES6变量提升
console.log(a) // Uncaught ReferenceError: a is not defined
let a = 1
console.log('a' in window) // false
这里的提示是not defined, 而不是输出undefined,并且window中也没有属性a, 说明:
let声明被提升(初始化 和 赋值 没有被提升)。
3.补充:
有种说法是:let 的 声明 也没有被提升。
示例代码:
console.log(a, b) // Uncaught ReferenceError: b is not defined
var a = 1
console.log('a' in window) // true
我们引入b,只是为了在var a = 1之前停止代码运行,造成和上面ES6同样的错误环境。
- 在ES6 let的例子中,a被声明但没有被初始化
- 在ES5 var的例子中,a被声明并初始化为undefined
其实,ES6的 let、const还是有变量提升的,只是会形成 Temporal Dead Zone,在未初始化前使用会报错(Uncaught ReferenceError)。
(完)
网友评论