如何访问对象上下文和范围?

时间:2014-04-22 10:58:22

标签: javascript

我有一个这样的代码段:

/** @constructor */
Person = function() {
    // member method
    this.say = function() {
        return "I'm an instance.";
    }

    // inner function
    function say() {
        return "I'm inner.";
    }
}
// static method
Person.say = function() {
    return "I'm static.";
}

var p = new Person();
p.say();      //=> I'm an instance.
Person.say(); //=> I'm static.
// there is no way to directly access the inner function from here

我了解到了

function say() { ... }

完全相同
var say;
say = function() { ... }

相同
var say;
this.say = function() { ... }

那么为什么内部函数没有覆盖成员方法

----- ----- EDIT
我仍然感到困惑,是this包含所有局部变量的对象?我们在这里举几个例子。

// Tested both in node.js and Chrome 34
var t = "stackoverflow";
console.log(t); //=> stackoverflow
console.log(this.t); //=> stackoverflow

所以这意味着,当我声明一个局部变量时,我可以通过this关键字访问它。

// Tested both in node.js and Chrome 34
this.t = "stackoverflow";
console.log(t); //=> stackoverflow
console.log(this.t); //=> stackoverflow

这意味着,当我将属性分配给this时,我可以通过本地范围访问它。这令人困惑!这就像函数有两个wrappers,一个是上下文this,另一个是范围?
所以现在我理解这种机制的方式是:

  • 假设我在范围内声明了一个变量,我们将其命名为tmp。然后,如果我通过this访问它,JSVM将首先查找this以查看this.tmp是否存在。如果没有,它将寻找tmp。如果找不到,那么我会得到undefined
  • 我在this中声明了一个变量,我们将其命名为this.tmp。然后,如果我通过简单地编写tmp来访问它,JSVM将首先查找范围以查看tmp是否存在。如果没有,则会看到this.tmp是否存在。如果找不到,那么我会得到undefined

我是对的吗?

2 个答案:

答案 0 :(得分:2)

当你说

时,你有一个错误
var say;
say = function () { ... }

相同
var say;
this.say = function () { ... }

并了解您需要了解this关键字的原因。此关键字包含对使用它的函数所属的对象的引用。在构造函数内部时,您希望引用正在构造的对象,因此使用this。在这种情况下,当您将某些内容放入this时,您将其放入构造函数将生成的对象中。

从这个意义上讲,第二个代码块将为您提供一个具有一个属性say的对象,该属性恰好是一个函数。

在javascript中使用构造函数时,对象将展示的唯一内容是使用this关键字将其赋予它的内容。另一方面,内部函数是一个在构造函数范围内的函数,可以在那里使用,但是没有公开,因为你不是这样想的。

将它与构建对象文字的此函数进行比较:

function buildMyObject() {

    function doSomething (obj) { ... }

    var objToBuild = { };

    doSomething(objToBuild);

    return objToBuild;
}

在这种情况下,可能是方便的,你定义一个函数来对你的对象做一些事情,并在构建你的对象的这个函数中使用它。返回该对象,但是看到对其执行的函数是隐藏的,因为它只在buildMyObject的范围内。这类似于构造函数内部函数的情况:它们提供了在构造函数中可能会发现有用的实用程序,但由于范围的原因,它们会被外部世界隐藏。

编辑: this关键字可以简要描述如下:当您在函数中使用它时,this包含对函数所属对象的引用。换句话说,this函数保存对当前实例的引用,即保存函数的实例。

现在是你的第一个例子

// Tested both in node.js and Chrome 34
this.t = "stackoverflow";
console.log(t); //=> stackoverflow
console.log(this.t); //=> stackoverflow

为什么会这样?好吧,因为在这种情况下,函数所属的对象只是window。在这种情况下,tthis.t都是相同的,因为this包含对window对象的引用。

虽然使用this时必须注意范围,因为它取决于范围,但此关键字只是对具有使用它的函数的对象进行此引用。

答案 1 :(得分:1)

this.sayPerson.say分配给对象的属性。内部函数是函数范围内的局部变量,而不是对象的属性。