'this'在原型函数中的函数中

时间:2011-01-15 17:01:45

标签: javascript

我基本上有一个对象,通过其原型扩展了一个函数。在该函数内部,存在另一个函数,但是当在此嵌套函数中使用this时,它似乎不是引用该对象,而是函数。

例如,

var sampleObject = function() {
 this.foo = 123;
}

sampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 }
 return nested();
}

var test = new sampleObject();

window.alert(test.getFoo()); // undefined

this.foo未引用123值,但未定义,因为它指的是嵌套函数,其中不存在foo。如何从嵌套函数中访问123值?

8 个答案:

答案 0 :(得分:35)

sampleObject.prototype.getFoo = function() {
 var me = this;
 var nested = function() {
  return me.foo;
 }
 return nested;
}

通过将this的值保存在局部变量中,可以使其明确地成为该函数和所有嵌套函数作用域的词法上下文的一部分。因此,在对“嵌套”的调用中,该内部函数将具有其自己的范围(它自己的this值),但它仍然可以引用封闭范围中的变量“me”。

答案 1 :(得分:8)

常见的解决方法是使用闭包

sampleObject.prototype.getFoo = function() {
  var _this = this; 
  var nested = function() {
    return _this.foo;
   }
   return nested();
}

一些库添加了自动化

的方法

答案 2 :(得分:7)

在您的示例中,“this”指的是窗口对象,因为在调用嵌套函数时没有指定另一个上下文,并且因为window.foo未定义而导致未查找。

您可以通过3种方式解决此问题。

1 - 使用变量存储外部 - 最常用的方法

sampleObject.prototype.getFoo = function() {
 var _this = this;
 var nested = function() {
  return _this.foo;
 }
 return nested();
}

2 - 使用将外部“this”绑定到内部

的bind方法
sampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 }.bind(this);
 return nested();
}

3 - 使用可以将上下文传递给函数

的调用方法
SampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 };
 return nested.call(this);
}

答案 3 :(得分:5)

TL;博士

使用arrow functions。它们自ECMAScript 6以来可用:



var sampleObject = function() {
  this.foo = 123;
}

sampleObject.prototype.getFoo = function() {
  var nested = () => { // Changed this line.
    return this.foo;
  }
  return nested();
}

var test = new sampleObject();

window.alert(test.getFoo());




解释

这是箭头功能的主要优点之一。您的案例在以下部分中进行了描述:No binding of this。参考指出:

  

在箭头函数之前,每个新函数都定义了自己的this值[...]   箭头函数不会创建自己的this上下文,因此this具有封闭上下文中的原始含义。

答案 4 :(得分:4)

除了将其声明为var _this = this之外,我还会看到代码正在执行var that = thisvar self = this

了解变量的范围很重要,因为它可能会产生意外结果。

答案 5 :(得分:1)

这是一个老问题,但为了完整起见,我给出了另一个解决方案。另一种方法涉及function binding

sampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 }
 return nested.bind(this)();
}

答案 6 :(得分:0)

这是一个关于JavaScript的已知疣。通常的模式是将它分配给外部函数中的另一个变量(通常是self),然后从内部函数访问self。这很有效。

答案 7 :(得分:0)

ES6的一种实现方法是使用Arrow Function。基本上,当您使用箭头功能时,它不会创建它自己的“ this”上下文。因此,使用“ this”将引用父函数的上下文。代码如下:

sampleObject.prototype.getFoo = function() {
    const nested = () => {
        return this.foo; //"this" refers to parent function's context
    }
    return nested;
}