在JavaScript中,call
、apply
和bind
是Function
对象自带的三个方法,这三个方法的主要作用是改变函数中的this
指向。今天,我把我所了解的记录下来,希望也能给初学者带来帮助!
1.call
语法:
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明: call
方法可以用来代替另一个对象调用一个方法。
call
方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
thisObj
的取值有以下4种情况:
(1) 不传,或者传null,undefined, 函数中的this指向window对象
(2) 传递另一个函数的函数名,函数中的this指向这个函数的引用
(3) 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean
(4) 传递一个对象,函数中的this指向这个对象
function a(){
console.log(this); //输出函数a中的this对象
}
function b(){}
var c={name:"call"}; //定义对象c
a.call(); //window
a.call(null); //window
a.call(undefined); //window
a.call(1); //Number
a.call(''); //String
a.call(true); //Boolean
a.call(b); //function b(){}
a.call(c); //Object
了解了上面这些过后,我们来个例子:
function class1(){
this.name=function(){
console.log("我是class1内的方法");
}
}
function class2(){
class1.call(this);
}
var f=new class2();
f.name();
毫无疑问,控制台打印:
"我是class1内的方法"
但是,到这里可能有的童鞋就不是太明白了,到底是谁指向谁?
class1方法没什么好说的,我们来看class2,我看到有很多人包括一些知名博客都给出这样的解释:
class1.call(this); //此行代码执行后,当前的this指向了class1(也可以说class2继承了class1)
我刚开始看到这样的解释,反正是一脸懵逼的状态,按照前面的定义,难道不是class1的this指向class2的this吗?实践出真知,于是把代码稍稍改一下,并运行如下:
function class1(){
console.log(this); // class2 {}
console.log(this.bug); // bug
this.name = function(){
console.log('我是class1内的方法');
}
}
function class2(){
this.bug = 'bug';
class1.call(this);
}
var f=new class2();
f.name(); // 我是class1内的方法
实践证明,我的想法还是正确的,class1的this指向class2的this,简单点说这两个this都是指向同一个地址,打印f如下:
所以f.name(); 自然会打印"我是class1内的方法"。