this指向
this只有在面向对象的时候才有意义,虽然是每个函数都有this,这是因为所有的函数都是定义在window对象上的方法,而方法只有在调用的时候才有this,指向那个调用自己的对象。
function as(a,b){
a = 2;
b = 3;
console.log(this)//window
return a+b;
}
as(1,2);//5
console.log(a)//a is not defined
因为a是形参所以并没有定义。
function as(a,b){
this.a = 2;
this.b = 3;
console.log(this)//window
return a+b;
}
as(1,2);//3
console.log(a)//2
a在这里是定义到了window上的实际变量,因此外部可以访问,as变成了
(a,b)=>a+b
function as(a,b){
this.a = 2;
this.b = 3;
console.log(this)//{a:2,b:3}
return a+b;
}
console.log(new as(1,2));//{a:2,b:3}
console.log(a)//a is not defined
同理,这段as变成了一个构造函数,new创建了一个空对象,然后调用apply方法,然后this指向这个空对象,所以构造函数中的this指向构造出来的对象。
此外
//返回一个对象
function fn(){
this.user = 'jack';
return {};
}
var a = new fn();
console.log(a.user); //undefined
//返回一个函数对象
function fn(){
this.user = 'jack';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
//返回一个值,num或者string
function fn(){
this.user = 'jack';
return undefined;
}
var a = new fn;
console.log(a.user); //jack
//返回null对象
function fn(){
this.user = 'jack';
return null;
}
var a = new fn;
console.log(a.user); //jack
因此,如果return了一个非null的对象,那么this就会指向那个对象,否则this就会指向函数构建的实例。
var package ={
size:100,
say:function(){
console.log(this.size)
}
}
package.say();//100
this的指向只有在方法调用的时候才能决定。
var example={};
example.size = 200;
example.say = package.say;
example.say()//200;
1.如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的是undefined。
2.如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
3.如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。
注意:
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
typeof j ;//function
j();
如果直接调用o.b.fn(),那么a=12
因为方法总是在执行的时候才会决定this指向,而j则是定义在window上的方法。
与构造函数 var person = new Person()不同,因为new关键字返回了一个实例,然后赋值,与方法的赋值是不同的。
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = function () {
return new Date().getFullYear() - this.birth; // this指向window或undefined
};
return fn();
}
};
在es6中,箭头函数解决了函数指向不明的问题。
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = () => new Date().getFullYear() - this.birth;
//this指向obj对象
return fn();
}
};
obj.getAge(); // 25
其实通过babel编译会发现其实是使用了类似that,self这种方式缓存了this的指向