9

我编写代码如下,

function Myfunction(){
 Myfunction.myvar = "somevar";
}

执行该功能后,我可以访问Myfunction.myvar

它是如何工作的?如果我这样做,隐藏在其中的问题是什么?

如果有任何问题,请解释其上下文。

4

4 回答 4

6

由于该函数在您调用它之前不会执行,Myfunction.myvar因此不会立即评估。

一旦你调用它,函数定义就被安装为Myfunction,所以当你调用它时它可以被解析。

像下面这样的东西是行不通的:

var x = {
       foo: 1,
       bar: x.foo } // x does not exist yet.
于 2013-07-31T10:22:58.063 回答
5

它是如何工作的?

当您在某个执行上下文中声明一个函数时,会向该上下文的变量环境添加一个绑定。当您引用一个标识符时,会检查当前变量环境以查看该标识符是否存在绑定。

如果不存在绑定,则检查外部变量环境,依此类推,返回到全局范围。

所以:

// OUTER SCOPE
// Binding exists for 'example'
function example() {
    // INNER SCOPE
    // No binding for 'example'

    // References 'example' in outer scope
    example.x = 1;
}

这其中隐藏着什么问题?

没有(通常......虽然它是否适合您的解决方案取决于您要做什么)。

您正在有效地创建函数的“静态”属性。由于 JavaScript 函数是一流的,因此您可以像设置任何其他对象一样在它们上设置属性。


请注意,如果您有一个命名函数表达式,而不是函数声明,则行为会有所不同:

var x = function example () {
    // Identifier 'example' is only in scope in here
};
于 2013-07-31T10:24:12.990 回答
2

由于范围界定,您可能会遇到一个问题,如一个更复杂的示例所示:

function Other() {
    console.log("a) Other.Myvalue",Other.Myvalue);
    Other.Myvalue=typeof Other.Myvalue==='undefined' ? 0 : Other.Myvalue+1;
    console.log("b) Other.Myvalue",Other.Myvalue);
}
Other();
Other();

这将导致

a) Other.Myvalue undefined
b) Other.Myvalue 0
a) Other.Myvalue 0
b) Other.Myvalue 1 

所以你真的将你的变量 Myvar 绑定到函数对象本身,它是一个单例并且只存在一次(并且由函数定义本身在当前上下文中创建,可能是全局上下文),而不是该对象的实例。但是如果你只使用静态值并且不需要任何逻辑,它就像字面量形式,我不希望有任何问题,除了字面量形式更方便:

var Other = {
  Myvalue: "somevalue"
};
于 2013-07-31T10:53:48.413 回答
0

在 javascript 中,每个函数都是一个对象。因此,您可以向其中添加任何自定义字段。

function A() {}

A.somevar = 'this is custom field';

A.prototype.somevar2 = 'this is field in A proto';

因此,当您使用 A 构造函数创建新对象时,它将从原型中获取属性。

var b = new A();
alert(b.somevar2);
于 2013-07-31T10:26:33.313 回答