this提供了一种更优雅的方式来“隐式”传递一个对象的引用,
eg:
function identify() {
return this.name.toUpperCase();
}
function speak() {
var greeting = "Hello, I'm " + identify.call( this );
console.log( greeting );
}
var me = {
name: "Kyle"
};
var you = {
name: "Reader"
};
identify.call( me ); // KYLE
identify.call( you ); // READER
speak.call( me ); // Hello, 我是 KYLE
speak.call( you ); // Hello, 我是 READER
如果不用this,则需要显示传递一个上下文对象
绑定规则
this是在运行时进行绑定的,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系。
1.默认绑定
直接使用不带任何修饰符的函数引用进行调用使用默认绑定,this
被绑定到全局对象。
NOTE:在严格模式中,全局对象将无法使用默认绑定,this
会等于undefined
2.隐式绑定
调用时使用object上下文来引用函数,隐式绑定将函数中的this绑定到这个object
NOTE:丢失绑定对象的情况
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo; // 函数别名!
var a = "oops, global"; // a 是全局对象的属性
bar(); // "oops, global"
虽然bar
是obj.foo
的一个引用,但它引用的是foo
函数本身,因此此时bar()
是一个不带任何修饰符的调用,采用默认绑定
3.显式绑定
call()和apply()
foo.call(foo,i);
使用call()
可以确保this指向函数对象foo本身
硬绑定
Function.prototype.bind会返回一个硬编码的新函数,它会把参数设置为this的上下文并调用原始函数,除了new时
软绑定
保留隐式绑定或显式绑定修改this的能力
4.new绑定
使用new来调用函数会放生:
- 创建(或者说构造)一个全新的对象。
- 这个新对象会被执行 [[ 原型 ]] 连接。
- 这个新对象会绑定到函数调用的 this。
- 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。
NOTE:
1如果把null或undefined作为this的绑定对象传入call,apply或者bind,这些值在调用时会被忽略,实际应用的是默认绑定规则
2.箭头函数的this是外层作用域。