正在设置字段和'带有'陈述

Setting fields on and object referenced by the 'with' statement

本文关键字:带有 陈述 设置 字段      更新时间:2023-09-26

在JavaScript中,我模拟如下类:

function MyClass() {} // Constructor
MyClass.prototype.myField = "foo";

我想通过使用with关键字:来提高代码的可读性并节省按键次数

function MyClass() {} // Constructor
with (MyClass.prototype)
{
    myField = "foo";
    myOtherField = "bar";
    myMethod = // etc
}

但是,如果我创建一个实例并尝试访问其中的任何字段,它们就是undefined。然而,如果我执行with (MyClass.prototype),然后尝试从中读取值,这是有效的——只有当我尝试更改它们或创建新字段时,它才会失败。我假设这是因为with (myObject)将您的范围限定为myObject的克隆,而不是对原始实例的实际引用。

那么,有什么办法绕过这个吗?有没有办法产生我想要的结果,有没有with?还是我注定要一遍又一遍地写出MyClass.prototype

"如果我创建一个实例并尝试访问这些字段中的任何一个,它们就是undefined"

不能以这种方式创建新字段。

"如果我执行with (MyClass.prototype),然后尝试从中读取值,则有效"

这是因为您可以读取和更新现有字段。

"我认为这是因为with (myObject)将您定位到myObject的克隆,而不是对原始实例的实际引用。"

不,这是对对象的实际引用。


这种困惑是人们避免使用with的部分原因。


"那么,有没有办法绕过这一点?有没有办法产生我想要的结果,有没有?或者我注定要一次又一次地写出MyClass.prototype?"

只需使用一个变量。

var p = MyClass.prototype;
p.myField = "foo";
p.myOtherField = "bar";
p.myMethod = "etc";

您也可以覆盖现有的原型对象,允许对象文字符号。。。

function MyClass() {}
MyClass.prototype = {
    myField: "foo",
    myOtherField: "bar",
    myMethod: "etc"
};

如果需要,也可以添加constructor: MyClass

看看这篇文章,它解释了为什么不应该使用with语句-myField、myOtherField和myMethod变量将在代码中创建为全局变量,因为它们还没有作为原型对象的属性存在。