构造函数中的 JavaScript 访问器属性

标签 javascript oop design-patterns constructor

我见过通过对象字面量和属性描述符中的 getset 关键字定义的访问器属性。

(来自 Speaking JavaScript ):

// Object literal
var obj = {
    get foo() {
        return 'getter';
    },
    set foo(value) {
        console.log('setter: '+value);
    }
};

// Property descriptor
var obj = Object.create(
    Object.prototype, {  // object with property descriptors
        foo: {  // property descriptor
            get: function () {
                return 'getter';
            },
            set: function (value) {
                console.log('setter: '+value);
            }
        }
    }
);

(来自 Eloquent JavaScript ):

// Adding to an object's prototype
Object.defineProperty(TextCell.prototype, "heightProp", {
  get: function() { return this.text.length; }
});

但是假设您正在使用构造函数 来创建对象。我还没有看到在构造函数本身中定义访问器的示例(即访问器是对象的自有属性。)

在构造函数中使用 Object.defineProperty 似乎可行:

function V(x, y) {
    this.x = x;
    this.y = y;
    // accessor (getter) `length`
    Object.defineProperty(this, 'length', {
      get: function () { return Math.sqrt(this.x*this.x + this.y*this.y); } // (1)
    });
}

上面构造函数中(1)中定义的访问器属性与早期模式(对象字面量、直接在对象上的属性描述符)中定义的访问器属性有什么不同吗?

(除了编​​码风格偏好之外,是否有客观原因不在构造函数中定义 getter 和 setter?)

最佳答案

Is there any difference in the accessor property defined as in (1) in the constructor above, and accessor properties defined as in the earlier patterns (object literals, property descriptors directly on the object)?

(1)和你之前使用defineProperty没有区别,没有。它与顶部的对象初始值设定项 (var obj = ...) 之间存在差异:foo 属性是可枚举,而您的 (1) 示例中的 length 属性和 Eloquent JavaScript 示例中的 heightProp 不是(因为 defineProperty 的默认值是定义它不可枚举;您可以通过添加 enumerable: true 来更改它。

(And are there objective reasons not to define getters and setters in constructors outside of coding style preference?)

没有。不过,我会注意到,您的特定示例并不能从自己的属性(property)中受益;所以我可能会在 V.prototype 上定义它。但除了使用原型(prototype)上定义的东西的通常好处(共享、可重用性、动态性)之外,没有特别的理由更喜欢它。定义一次意味着更少的函数对象,但对象相当便宜。

关于构造函数中的 JavaScript 访问器属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36639300/

相关文章:

javascript - 如何在 Javascript 中按任意键触发函数?

javascript - Jquery 鼠标单击事件不适用于某些功能

javascript - 使用 JavaScript 在单个函数内将数字数组转换为字符串,然后再转换回数字数组

c# - 访问说明符和访问修饰符之间的区别

c++ - 我如何使用 ' string::find ' 使用 C++ 在文件中查找单词

javascript - toLocaleString() 不适用于输入更改

javascript - ECMAScript 6 是否有抽象类的约定?

python - 在面向对象的 Python 中使用 ctypes 从 DLL 文件运行函数时出现问题

c++ - TreeView 中的分层数据和 TreeView 更新技术

c++ - 如何让多个类共享指向一个公共(public)类的指针