1、默认绑定规则:this指向windows
1、console.log(this === window) //true
2、函数独立调用,函数独立调用理解:test(),没有借助外物
function test( ){
console.log(this === windows)
};
test( )//true
每个函数执行都会产生一个this,this都不一样,具体指向可能是一样的,这个要看执行方式决定的
var obj ={
a: 2,
foo: function( ){
console.log(this);//obj
function test( ){
console.log(this);//window,test( )自身调用,指向window
}
test( );//函数声明,然后立即执行,相当于立即执行函数
}
};
(function ( ){
console.log(this);//window 相当于上面函数独立调用
})( );
拓展: 闭包概念–> 当函数被执行的时候,导致函数被定义,并抛出
var obj = {
a: 2,
foo: function( ){
function test( ){
console.log(this);
}
return test;
}
};
obj.foo( )( );//obj.foo( )= f test -> test( )独立调用,指向window
2、隐式绑定:谁调用指向谁
两个特殊会导致隐式绑定失败:1、变量赋值(隐式丢失) 2、参数赋值
// 特殊 变量赋值情况,也叫隐式丢失
function foo( ){
console.log(this);
};
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo;
bar( );//window -> obj.foo = f foo = bar -> bar( )相当于函数独立调用
//特殊 参数赋值情况
function foo( ){
console.log(this);
};
function bar(fn){
fn( );//fn = f foo -> fn( ) 函数独立调用
};
var obj = {
a: 2,
foo: foo
};
bar(obj.foo);//window
拓展:父函数有能力决定 子函数的this 指向
var arr = [1, 2, 3];
//里面的f有2种说法:1、以函数作为形参;2、回调函数,forEach是父函数,里面f是子函数
arr.forEach(function(item, idx, arr){
console.log(this);
}, this);
arr.sort(function(a, b){
console.log(this);
});
setInterval(function( ){
console.log(this);
});
3、显示绑定:call、apply、bind
obj.call(obj, 1, 2, 3)
obj.apply(obj, [1, 2, 3])
obj.bind(obj)(1, 2, 3)
//这三个方法,绑定this一定是个对象,如果不是对象,会导致绑定失败,会回到默认绑定,即window
1、obj.call(obj, 1, 2, 3)
2、obj.call(1, 2, 3);//1--> 通过new Number()包装类 --> Number(1)数字对象
3、obj.call(undefined, 1, 2, 3)//undefined 没有包装类,this --> window
obj.call(null, 1, 2, 3)//null没有包装类,this --> window
4、new 绑定
//需要注意:不要手动添加return { },因为会改变this指向,变为{ }
function Person( ){
this.a = 1;
return { };
};
var person = new Person();
console.log(person)//{}
this指向优先级: new 绑定 > 显示绑定 > 隐式绑定 > 默认绑定规则
理解:new关键字会单独造一个this出来,毋容置疑是最高
显示绑定,你是强制绑定,所以排第二
隐式绑定,因为你不用obj.方法调用,默认是window,所以高于默认
默认规则是最低的