指向问题
- 哪个对象调用函数,函数里面的this指向哪个对象。
- 严格模式下:在全局环境中,this指向的是
undefined
- 非严格模式下:在全局环境中,this指向的是
window
var name = 22
var a = {
name: 11,
say: function(){
console.log(this.name)
}
}
var fun = a.say
fun() // 相当于fun.call(window),结果22
a.say() // 相当于a.say.call(a),结果11
var b = {
name: 33,
say: function(fun){
fun() // 22
}
}
b.say(a.say) // 相当于fun(),结果22
b.say = a.say
b.say() // 相当于b.say.call(b),结果33
在函数中直接使用(window)
- 全局定义的函数直接调用,
this => window
function fn(){
console.log(this);
// 此时 this 指向 window
}
fn();
// 相当于 window.fn()
- 定时器的处理函数,
this => window
setTimeout(function(){
console.log(this);
},0)
// 此时定时器处理函数里面的this 指向 window
- 自调用函数,
this => window
(function () {
console.log(this)
})()
// 此时 this 指向 window
作为对象方法调用(调用者)
- 对象内部的函数调用,
this => 调用者
var obj = {
fn:function(){
console.log(this);
}
}
obj.fn();
// 此时 this 指向 obj
- 事件处理函数,
this => 调用者
div.onclick = function(){
console.log(this);
}
//当你点击 div 的时候,this指向 div
改变指向
刚才我们说过的都是函数的基本调用方式里面的 this 指向,我们还有三个方法可以忽略函数本身的 this 指向转而指向别的地方。这三个方法就是 call / apply / bind,是强行改变 this 指向的方法。
call/apply/bind
附加在函数调用后面使用,可以忽略函数本身的 this 指向call和apply
使用时会立即自动调用函数,bind
使用时会创建一个函数,但是需要另外去手动调用func.apply(this, arguments)
等价于func.call(this, ...arguments)
单个参数 call
- 语法:
fn.call(fn 函数体内 this 的指向哪里,arg1, arg2, ...);
- 作用:调用被绑定的函数fn,指定它的 this 指向并传参
- 参数:
- 第一个参数:是 this 指向
- 其余的参数:需要传入的值,可以是多个,用逗号隔开
- 使用
call
方法指定this
var name = 'Rose';
var obj = {name:'Jack'};
function fn(){
console.log(this.name);
}
fn(); // Rose
fn.call(); // Rose
fn.call(obj); // jack
- 使用
call
方法指定this
并传参
var obj = {name:'jack'};
function fn(a,b){
console.log(this,a,b);
}
fn(1,2); // window 1 2
fn.call(obj,1,2); // obj 1 2
fn(1,3); // window 1 3
创建函数 bind
- 语法:
fn.bind(fn 函数体内 this 的指向, arg1, arg2, ...);
- 作用:创建一个新的绑定函数,指定它的 this 指向并传参,必须调用它才会被执行
- 参数:
- 第一个参数:this 指向的对象
- 其余的参数:需要传入的值,可以是多个,用逗号隔开
- 使用
bind
方法指定this
var name = "rose"
var obj = {name:'jack'};
function fun(a,b){
console.log(this,this.name);
}
var funName = fun.bind(obj)
funName() // obj "jack"
- 使用
call
方法指定this
并传参
function fn(a,b){
console.log(this,a,b);
}
fn(1,2); // window 1 2
fn.bind(obj,1,2); // 未调用不执行
fn.bind(obj,1,3)() // obj 1 3
var newFn = fn.bind(obj,3,4);
newFn(); // obj 3 4
newFn(5,6); // obj 3 4
数组参数 apply
apply
方法接受的是一个包含多个参数的数组- 语法:
fn.apply(fn 函数体内 this 的指向哪里,[arg1, arg2, ...]);
- 作用:调用被绑定的函数fn,指定它的 this 指向并传参
- 参数:
- 第一个参数:this 指向的对象
- 第二个参数:一个包含多个参数的数组
- 使用
apply
方法指定this
var name = 'Rose';
var obj = {name:'Jack'};
function fn(){
console.log(this.name);
}
fn(); // Rose
fn.apply(); // Rose
fn.apply(obj); // jack
- 使用
apply
方法指定this
并传参
var obj = {name:'jack'};
function fn(a,b){
console.log(this,a,b);
}
fn([1,2]); // window 1 2
fn.apply(obj,[1,2]); // obj 1 2
fn([1,3]); // window 1 3