this到底是什么
当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包 含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this 就是记录的 其中一个属性,会在函数执行的过程中用到。 学习this 的第一步是明白:this 既不指向函数自身也不指向函数的词法作用域,this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
this绑定规则
1.默认绑定
独立函数调用。可以把这条规则看作是无法应用其他规则时的默认规则。如果使用严格模式(strict mode),那么全局对象将无法使用默认绑定,因此this 会绑定到undefined:
2.隐式绑定
调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含。 eg:
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
obj.foo(); // 2
3.显示绑定
可以使用函数的call(…) 和apply(…) 方法。它们的第一个参数是一个对象,它们会把这个对象绑定到 this,接着在调用函数时指定这个this。因为你可以直接指定this 的绑定对象,因此我们称之为显式绑定。 硬绑定:是一种显式的强制绑定,bind(…) 会返回一个硬编码的新函数,它会把参数设置为this 的上下文并调用原始函数。
4.new绑定
JavaScript 中new 的机制实际上和面向类的语言完全不同。 使用new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作:
- 创建(或者说构造)一个全新的对象。
- 这个新对象会被执行[[ 原型]] 连接。
- 这个新对象会绑定到函数调用的this。
- 如果函数没有返回其他对象,那么new 表达式中的函数调用会自动返回这个新对象。
eg:
function foo(a) {
this.a = a;
}
var bar = new foo(2);
console.log( bar.a ); // 2
使用new 来调用foo(…) 时,我们会构造一个新对象并把它绑定到foo(…) 调用中的this上。我们称之为new 绑定。
优先级
new>显示绑定>隐式绑定>默认绑定
更安全的this
想“更安全”地忽略this 绑定,可以使用一个DMZ 对象,它就是一个空的非委托的对象;在JavaScript 中创建一个空对象最简单的方法都是Object.create(null)。Object.create(null) 和{} 很像, 但是并不会创建Object.prototype 这个委托,所以它比{}“更空”。
箭头函数
箭头函数的this无法被修改。
注:你不知道的JavaScript上第二部分第一、二章读书笔记
|