this 到底是什么
this是在运行时绑定的,并不是在编写时绑定,他的上下文取决于函数调用时的各种条件,只取决于函数的调用方法。
当一个函数调用时,会创建一个执行上下文,这个上下文会包含函数的调用栈、函数的调用方法和传入的参数等信息。this就是执行上下文的一个属性,在函数的执行过程中用到。
this绑定的绑定
函数的执行过程中调用位置决定了this的绑定对象。
默认绑定
在非严格模式下函数的默认绑定为全局对象(浏览器中为window
), 严格模式下的默认绑定为undefined
function foo(){
console.log(this.a)
}
//变量a的声明默认为全局对象的一个属性
var a = 2;
//非严格模式下this指向了全局对象
foo() //2
隐式的绑定
隐式的绑定的是指函数的调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含。
function foo(){
console.log(this.a)
}
var obj = {
a:2,
foo:foo
}
//foo函数执行过程中this默认绑定为obj对象。则 this.a=obj.a
obj.foo() // 2
隐式丢失
隐式丢失指被隐式的绑定的函数会丢失绑定的对象,从而应用于默认绑定。
function foo(){
console.log(this.a)
}
var obj = {
a:2,
foo:foo
}
var a = "zhang san"//a为全局对象的属性
var bar = obj.foo//将obj.foo引用的函数地址赋值给bar 从而导致bar引用的函数失去隐式绑定
bar()//zhang san
//回调函数丢失this绑定式非常常见的
setTimeout(obj.foo, 100) //zhang san
显示绑定
显示绑定是指利用call(...)
或apply(...)
函数直接指定this的绑定对象。
function foo(){
console.log(this.a)
}
var obj = {
a:2,
foo:foo
}
foo.call(obj)//2
硬绑定
硬绑定是一种显示的强制绑定
function foo(something){
console.log(this.a,something)
return this.a + something
}
function bind(fn, obj){
return function(){
fun.apply(obj,arguments);
}
}
var obj = {
a:2,
}
var bar = bind(foo, obj);
var b = bar(3);//2 3
console.log(b); //5
硬绑定是创建一个包裹函数, 传入所有的参数并返回接收到的所有值。
在ES5中提供了内置的方法Function.prototype.bind
function foo(something){
console.log(this.a,something)
return this.a + something
}
var obj = {
a:2,
}
var bar = foo.bind(obj);
var b = bar(3);//2 3
console.log(b); //5
new绑定
使用new来调用函数或者说是发生构造函数调用时,会自动执行下面的操作:
- 创建一个全新的对象。
- 这个新的对象会被执行原型链接。
- 这个新对像会绑定到函数调用的this。
- 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新的对象。
function foo(a){
this.a = a;
}
var bar = new foo(2);
console.log(bar.a); //2
优先级
new绑定 > 显示绑定 > 隐式的绑定 > 默认绑定
判断this
- 由
new
调用?绑定到新创建的对象。 - 由
call
或者apply
(或者bind
)调用?绑定到指定的对象。 - 由上下文对象调用?绑定到那个上下文对象。
- 默认:在严格模式下绑定到
undefined
,否则绑定到全局对象。
网友评论