this指向

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的指向

posted @ 2017-04-02 22:15  慕迪亚  阅读(120)  评论(0编辑  收藏  举报
你的浏览器不支持canvas