this指向性的问题汇总
一、因为JavaScript中的this是在运行期绑定的,因此JavaScript中的this关键字具备多重含义。
二、具体在应用中,this的指向大概可以分为以下四种。
1.作为对象的方法调用 obj.run()
2.作为普通函数调用 function()
3.作为构造函数调用 var b =new a();
4.function.prototype.call或者function.prototype.apply调用
三、作为对象的方法调用和作为普通函数调用
window.name=bj;
var obj={
name:zzy,
getName(){
console.log(this.name)
}
}
obj.getNAme();//输出的zzy
var getA=obj.getName;
getA(); //输出的为bj
不管getA之前是getNAme(),还是其他某个对象的属性,只要最后是以getA(),这种方式调用的,均视为普通函数调用,此时this指向window对象
但是,在ES5的strict模式下,作为函数调用的 this被规定不会指向全局对象
getA(); //输出的为underfined
四.构造函数的调用
通常情况下,构造函数里的this指向那个返回的这个对象,但是如果构造器显示的返回了一个object类型的对象,则this指向返回的object对象
var Myclass = function(){
this.name = 'beidan';
}
var obj = new Myclass();
console.log(obj.name);//beidan
var Myclass = function(){
this.name = 'beidan';
return{ //显示的返回一个对象,注意!既要是显示,即有return,也要是对象{}
name:'test'
}
}
var obj = new Myclass();
console.log(obj.name);//test
五.function.prototype.call或function.prototype.apply调用
call,apply都是为了改变函数内部this的指向。例如,function.apply()或者
function.apply()都是为了改变函数内部的this指向。
二者的作用完全一样,只是接受参数的方式不太一样。
function.call(this, arg1, arg2); //参数列表arg1,arg2
function.apply(this, [arg1, arg2]); //参数数组 [arg1,arg2]
第一个参数,指定了那个函数体内this对象的指向,它可以是javascript对象,如果为null,则函数体内的this会指向默认的window
第二个参数,call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。当参数不确定数量时用 apply ,然后把参数 push 进数组传递进去。或者也可以通过 arguments来获取所有的参数。这样看来,apply的使用率更高。
1.修正this指向
在实际开发过程中,会出现一下的情况
document.getElementById('div1').onclick = function(){
console.log(this.id); //div1
var func = function(){
console.log(this.id);
}
func(); //通过普通函数调用,this指向window,输出undefined
}
使用call来改变this的指向
document.getElementById('div1').onclick = function(){
console.log(this.id); //div1
var func = function(){
console.log(this.id);
}
func.call(this); //使func函数内部的this指向当前的函数对象,输出div1
}
2.模拟继承
function fruits() {}
fruits.prototype = {
color: "red",
say: function() {
console.log("My color is "+ this.color);
}
}
var apple = new fruits;
apple.say(); //My color is red
但是,如果我们还有其它 2个对象 banana= {color : "yellow"} ,orange = {color:‘orange’},想使用say方法,但是又不想对它们重新定义say方法。
那么,我们可以用apply或者call 借用 fruit里面的say方法
banana = {color: "yellow"};
orange = {color:‘orange’};
apple.say.call(banana); //My color is yellow
apple.say.apply(orange ); //My color is orange
这里需要注意的是banana继承apple.say的方法;