【问题标题】:Javascript: when using Object literal, does ordering of properties matters?Javascript:使用对象文字时,属性的顺序是否重要?
【发布时间】:2015-08-28 10:55:42
【问题描述】:

以下示例来自: http://www.phpied.com/3-ways-to-define-a-javascript-class/

var apple = {
    type: "macintosh",
    color: "red",
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    }
};

现在我将 getInfo() 方法移到我的对象声明的顶部。

var apple = {
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    },
    type: "macintosh",
    color: "red",
};

apple.getInfo();
red macintosh apple

我预计 javascript 解析器/编译器会失败,因为 this.color 和 this.type 尚未定义。这在内部是如何工作的?

(这个问题最初是这里的 ExtJS 框架问题:ExtJS: settings properties via a function on the Prototype: is it a safe pattern?,但我意识到这是一个更一般的 javascript 问题,因此是这个新问题)

【问题讨论】:

  • 一旦你调用apple.getInfo();,整个苹果对象就已经被定义了。
  • 好问题,问得好。
  • 即使您向此函数添加了永远不会定义的属性,解析器也不会失败。这与 JavaScript 是 [en.wikipedia.org/wiki/Duck_typing](Duck Typed) 的事实有关。
  • 正如@hege_hegedus所说,第8行的}之后应该有一个分号。

标签: javascript prototype


【解决方案1】:

函数内部的代码在您调用它之前不会执行,因此this 的属性color 在调用apple.getInfo() 之前不会计算。

编辑:

var apple = {
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    },
    type: "macintosh",
    color: "red",
    }
}

此时定义了apple对象,getInfo属性是一个函数,会在评估时返回属性``

apple.getInfo();

现在对函数进行求值,此时属性colortype 已明确定义

函数在求值时获取这些属性的值,因此如果属性colortype发生变化,函数的返回值也会发生变化。

【讨论】:

  • "此时定义了苹果对象,getInfo 属性是一个函数,在计算时会返回属性"这是我缺少的部分,谢谢。
【解决方案2】:

创建实例后调用该函数。定义后,它不会运行,也不会尝试访问属性,但是在您调用 getInfo() 函数的地方,它们都存在。事实上,无法在解析单个属性的解释器之间运行任何自定义 JavaScript 代码。

【讨论】:

    【解决方案3】:

    我预计 javascript 解析器/编译器会失败,因为 this.color 和 this.type 尚未定义。

    编译器中的解析器并不关心。 JavaScript 不会评估是否可以找到属性或变量,直到使用它的代码执行。在属性的情况下,一个尚不存在的属性会被创建(如果您正在写入)或导致值undefined(如果您正在从中读取),所以即使您的对象没有colortype 属性,代码仍然不会抛出错误。你只会得到字符串"undefined undefined apple"

    Javascript:使用 Object 字面量时,属性的顺序是否重要?

    重要吗? 可能不是。 有意义吗? 是的,从最新规范 ES6(又名 ECMAScript 6 又名 ECMAScript 20150)开始。对象初始化程序中属性的顺序决定了属性的创建顺序,这反过来又部分设置了for-in 循环访问它们的顺序,它们在Object.keys 数组中出现的顺序等。(部分设置因为可以强制转换为整数的属性名称的处理方式不同。)但你很少关心。 this answerthis answer 中的详细信息(后者主要是关于数组,但也涉及非数组对象)。

    【讨论】:

    • 这反过来又设置了它们被 for-in 循环访问的顺序”。你确定吗?我没有 see it statedObject.keys 说“If 实现定义了 for-in 语句的特定枚举顺序......”(我的重点)。 “如果”很重要。有许多对“按列表顺序”的引用,但没有定义对象属性的列表顺序(除了明显的源顺序)。
    • 有点混乱。内部Enumerate method says没有指定枚举属性的机制和顺序,但必须符合下面指定的规则”,然后[OwnPropertyKeys]()说“…按属性创建顺序…”。我想我已经说服自己了。或者进入它。随便。
    • @RobG:是的,我确定。如此多的引擎都在这样做(但相对于索引样式属性与非索引样式属性略有不同),他们决定指定它。我会看看我是否可以在我拿出砍刀的地方找到我的答案,并通过规范来确定它是否真的是真的。 :-)
    • @RobG:添加了指向答案的链接,这些链接是我通过规范记录我的黑客行为的其他答案。
    • 谢谢,不过还是一团糟,因为无论何时添加数字键(在符合 ECMAScript 2015 的实现中),数字键始终排在第一位且始终按数字顺序排列,但我仍然没有得到“ Object.keys 的 if”。如果 Arrays 和 Objects 是完全独立的对象,也许可以解决这个问题,但是属性枚举规则似乎试图同时适应两者,但又没有真正适应。
    猜你喜欢
    • 2021-11-20
    相关资源
    最近更新 更多