上QQ阅读APP看书,第一时间看更新
7.4 内部函数中的this
我们先来看一个例子。
var v = 1; function Program(){ var v = 2; this.v = 3; }
Program.prototype.logV = function () { function innerLog(){ console.log(this.v); } innerLog(); } var pro = new Program(); pro.logV();
大家觉得上述代码会打印出什么呢?可能有的读者觉得很简单,既然是pro对象调用的,当然会打印出pro对象中v的值3。但是,实际上1才是正确答案。在这个例子中,需要注意实际的打印操作并不是在logV方法中执行的,而是在logV中调用它的内部方法innerLog来完成的,因此这里的this应该指向innerLog方法前的对象,而不是logV方法前面的对象,而innerLog方法是直接调用的,前面并没有对象,这种情况下的this就会指向全局对象window,而window的v属性就是全局变量v,所以结果会打印出1。
这时,如果我们想在内部函数中打印出调用外部函数的对象的属性(例如,在innerLog方法中打印出pro对象中的v属性),那么有三种方法可以实现:第一种,在外部方法中将this保存到一个变量然后在内部函数中调用;第二种,在外部方法中将内部方法关联到对象上并使用对象调用内部方法;第三种,将内部方法改为接收参数的方法,并在外部方法中将属性通过变量传入内部方法。例如,上述代码中的logV方法可以这么处理。
方法1:
Program.prototype.logV = function () { var instance = this; function innerLog(){ console.log(instance.v); } innerLog(); }
方法2:
Program.prototype.logV = function () { function innerLog(){ console.log(this.v); } this.innerLog = innerLog; this.innerLog(); }
方法3:
Program.prototype.logV = function () { function innerLog(v){ console.log(v); }
innerLog(this.v); }
这三种方法都会打印出pro对象的属性v(3)。这里跟我们的原则“谁直接调用方法this就指向谁”并不冲突,只要注意实际处理业务的函数到底是谁调用的就可以了。