tcking/jsriver

理解this

Opened this issue · 1 comments

this表示当前上下文对象,概念比模糊,继续往下。
this出现的5种情况:

1在全局范围内:也就是在代码的顶层(没在函数或者对象声明),这时的this对象和宿主环境有关系,如果是浏览器环境,则是window对象。例如seajs源码通过命名包裹器将this传入闭包中,在浏览器环境下this就是window对象:
(function(global){
    global.fx=function(){//对外提供接口

    }
})(this)
2 在函数内(注意和在“方法内”区别):和在全局范围内一样,不管是函数内部(构造函数)的函数,只要没有通过对象调用其this就是全局对象。
window.name="testWindow"
function cat(){
    this.name="cat";
    function afterCreate(){
        alert("created a "+this.name);//此处的this是window对象
    }
    afterCreate();
}

new cat();// 输出 “created a testWindow” ,this.name就是window.name
3在方法内(注意和“在函数”内的区别是一个直接调用函数,一个通过对象调用函数):this指向的是当前执行方法的对象
window.name="testWindow"
var dog={
    name:'dog',
    say:function(){
        alert(this.name)
    },
    me:this.name,//相当于第一种情况,直接调用全局对象
    say2:function(){alert(this.me);}
}
dog.say() // "dog"
dog.say2()// "testWindow"
4在构造函数内(和new关键字一起使用的函数):this指向的是新生成的这个对象
window.name="testWindow"
function cat(){
    this.name="cat";
    this.say=function(){alert(this.name)}
    //return{say:function(){alert(this.name)}}
}

new cat().say();

需要注意的是:new出来的不一定是后面函数本身,这和函数的返回值有关系,如果函数返回了一个对象,那么new出来的就是函数返回的这个对象,例如:

window.name="testWindow"
function cat(){
    this.name="cat";
    this.say=function(){alert(this.name)}
    return{say:function(){alert(this.name)}}
}

new cat().say();

如果构造函数返回的不是一个对象(例如返回原始类型或者没有return,则new出来的就是函数本身)

还需要注意的是:方法调用的时候this是在运行时确定的,例如:

function Cat(){
    this.name="cat";
    this.say=function(){alert(this.name)}
}

Cat.prototype.say=function(){alert(this.name)}

function Dog(){
    this.name="dog";
}
Dog.prototype=Cat.prototype

var dog=new Dog();
dog.say() // "dog"
5通过Funciton中的call和apply更改this:其this显示的设置为第一个参数
function Cat(){
    this.name="cat";
    this.say=function(){alert(this.name)}
}

Cat.prototype.say=function(){alert(this.name)}

function Dog(){
    this.name="dog";
}
Dog.prototype=Cat.prototype

var dog=new Dog();
dog.say.call(new Cat())// "cat"

可总结为:谁调用了function,谁就是this