一、因为 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 的方法;