1.引言
this指向谁?这大概是js中的一大问题,尤其是对于我这个菜鸟来说,更是一道不可逾越的鸿沟,找了很多相关的博文,自己也进行了大量的Demo测试,有了些感悟,本篇是站在(彻底理解js中this的指向,不必硬背)的肩膀上加上自己的理解和一些更正完成的,姑且舔着脸算是原创的吧!再次声明本文不在于传道受业,旨在方便翻阅复习,文中若有纰漏,欢迎留言指出,不必留情。
2.this
//示例1
function test(){
var _name = "uncle";
console.log(this._name);
console.log(this);
}
test();
//示例2
var obj={
_name:"uncle",
func:function(){
console.log(this);
console.log(this._name);
}
}
obj.func();
//示例3
function test(){
console.log(this);
console.log(this._name);
}
var obj1={
_name:"uncle1",
func:test
}
var obj2={
_name:"uncle2",
func:test
}
obj1.func();
obj2.func();
示例1中的this指向的是window,而window下面并没有_name属性,所以输出undefined,可以猜测一下this为什么指向window?test函数调用 test() 实际上可以写成 window.test()【window是js中的全局对象,我们创建的变量实际上是给window添加属性】,this是不是指向的是调用它的对象啊,与this写在哪里无关啊?如果示例2不足以证明这一点,那么示例3总能打消你的所有疑虑吧,那么结论就来了:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(当然了这句话不够完善,后面会继续完善,耐心看完哦!)。如果这句话成立的话,在上面示例2中的函数调用 obj.func() 可以写成 window.obj.func() ,最终的调用对象是window,为什么不指向window啊,而是指向obj?
//示例4
var obj={
_name:"wuc",
b:{
_name:"uncle",
func:function(){
console.log(this);
console.log(this._name);
}
}
}
obj.b.func();
//示例5
var obj={
_name:"wuc",
b:{
_name:"uncle",
func:function(){
console.log(this);
console.log(this._name);
}
}
}
var obj1=obj.b.func;
obj1();
this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,a.b.c.d.e.f…..y.z(),this指向y,因此示例4中的this指向的是b,但是在示例5中this之所指向window,还是上面的那句话,this指向在调用的时候才能决定,调用的时候实际上等价于window.obj1()
//示例6
function Func(name,age){
this._name=name;
this._age=age;
}
var obj=new Func("uncle",25);
console.log(obj._name+":"+obj._age);
构造函数里面的this会指向将来实例化对象的,也就是new Object()后的对象,但是如果,构造函数里面添加return,会怎么样呢?
//示例7
function Programmer(){
//return 1;
//return "abc";
//return ["a","b",1];
//return {name:"uncle",age:21};
return function(){console.log("uncle")};
}
Programmer.prototype.code=function(){
console.log("coding with javascript...");
}
var coder=new Programmer();
console.log(coder);
//输出结果
//Programmer{}
//Programmer{}
//["a","b",1]
//Object {name:"uncle",age:21}
//function (){console.log("uncle")}
从示例7中可以看出,在JavaScript构造函数中,如果return值类型,那么对构造函数没有影响,实例化对象返回空对象;如果return引用类型(数组,函数,对象),那么实例化对象就会返回该引用类型。对于这一点,不妨来看看下面的示例8和示例9.
//示例8
function Func(name,age){
this._name=name;
this._age=age;
return{
_name:"uncle",
_age:25
};
}
var obj=new Func("wuc",26);
console.log(obj._name+":"+obj._age);
//示例9
function Func(name,age){
this._name=name;
this._age=age;
return "hehe";
}
var obj=new Func("wuc",26);
console.log(obj._name+":"+obj._age);
3.总结
- this指向在执行的时候才能确定
- 多重链式调用,this指向就近原则
- 注意构造函数的引用类型返回值问题
- call,apply,bind可以改变this指向