对javascript this的赋值有了深一层的理解后,看一下比较复杂的情况,this的应用篇参考《对javascript this的理解》.
#demo1
1 var name="window"; 2 var object = { 3 name:"me", 4 getname:(function(){ 5 alert(this.name);//window,加载即执行 6 return function(){ 7 return this.name; 8 } 9 })() 10 } 11 alert(object.getname());// window me
首先getname 属性指向的值是一个自执行方法,为了方便,我们称它为AutoExeFun,首先激活AutoExeFun,并且进入到AutoExeFun的执行上下文AutoExeFunContext,并把AutoExeFunContext压入执行堆栈,可以很清楚的看到,AutoExeFun既不是标识符,也不属于属性访问器,所以 line 5 的 this指针为全局的global, 执行完之后返回function(){return this.name},然后由object.getname()调用,属于属性访问器访问,line7的this则为object
#demo2
1 var name="window"; 2 var object = { 3 name:"me", 4 getname:(function(){ 5 var that=this; 6 return function(){ 7 return that.name; 8 } 9 })() 10 } 11 alert(object.getname());//window
#demo2和#demo1的区别在于line5 中 定义了that作为自执行function中this的引用,由demo1分析可见,line5中的this指向全局对象,在return 的function中,用到了that局部变量,由于外部可能会调用,所以即使退出自执行function的上下文,依然会保持对that的引用,具体可参考《关于javascript中的闭包》 ,所以执行结果为window
#demo3
1 var name="window"; 2 var object = { 3 name:"me", 4 getname:function(){ 5 var that=this; 6 return function(){ 7 return that.name; 8 } 9 } 10 } 11 alert(object.getname()());//me
#demo3的执行分为两部分,第一部分object.getname(),标记为Section A, 很明显A部分function的调用 属于属性访问器类型,所以解析成对象引用后,会把base->object,同时this->base,即line5的this和that都是指object,Section B 部分, 同时由于闭包保持了对that的引用,在SectionB的执行上下文中,that依然指向object
以上是几个关于this指针的demo,除全局的this外,function中this指针的赋值操作发生在function被调用的时候,即进入function所在的执行上下文期间。
贴上一段关于context的伪代码描述,参考文章为 what-is-the-execution-context-in-javascript,
executionContextObj = { scopeChain: { /* variableObject + all parent execution context‘s variableObject */ }, variableObject: { /* function arguments / parameters, inner variable and function declarations */ }, this: {} }
具体关于执行上下文的理解可参考 《关于javascript中的 执行上下文》。