【问题标题】:Config Property Shadowing配置属性阴影
【发布时间】:2013-06-23 19:06:27
【问题描述】:

开始在 JavaScript 中使用已配置的对象,但有些东西给我带来了一些问题。

查看此代码:

function Monster() {
}

function Animal() {
  Object.defineProperty(this, "name", {
    set: function(n) {  },
    get: function() { return "Jim"; } // hard-coded to demonstrate problem
  });
}

Monster.prototype = new Animal();

var monster = new Monster();
monster.name = "John";
monster.name // Still returns Jim. I need to assign the property to THIS object, so Jim is shadowed by John.

正如评论所说,这是输出“Jim”,因为 getter 被硬编码为返回。

我不想每次调用 monster.name 时都更改我的原型 - 我想要在我的怪物实例上添加一个新的阴影属性。我该如何处理?

【问题讨论】:

  • 您正在尝试使用 prototypical 继承来覆盖基类上的 per instance 属性。它不会起作用。
  • 那么有没有办法在不被原型定义吃掉的情况下分配monster.name?我不想更改我的原型,除非我直接尝试修改 monster.__proto__.name - 否则我希望 monster.name 指向该对象上的属性,而不是我的原型。
  • 我的回答对您有帮助吗?它展示了如何在不更改原型定义的情况下重新分配名称。

标签: javascript html oop


【解决方案1】:

您在 getter 函数中对“Jim”进行了硬编码,因此无论如何它都会返回“Jim”。您需要将属性的值存储在局部变量中并从那里获取它:

function Animal() {
  var myName = "Jim";
  Object.defineProperty(this, "name", {
    set: function(n) { myName = n },
    get: function() { return myName; }
  });
}

FIDDLE

【讨论】:

  • 几乎和我想的一模一样,在我还没来得及开始写作之前就发布了 +1。
  • 感谢您的帖子。但这是为了演示当我尝试在我的子类中覆盖该属性时,该属性是如何被正确隐藏的。
  • 正如我所说,如果您按字面意思写return "Jim";,那么这将始终是您的财产的价值,它实际上并没有证明任何东西。我不确定我是否完全理解你想要什么,但如果你按照我建议的方式定义你的属性,你可以简单地创建 Monster 实例并更改它们的名称值。查看更新的小提琴。
  • 如果animal没有使用defineProperty来创建它的属性,那么一个新的属性将会被分配给我的monster实例——阴影属性animal具有因此当我改变我的动物原型时不会修改我的Animal原型怪物实例。您的回答只是假设我在 defineProperty 函数上犯了一个愚蠢的错误。
  • @JJJ 你可以使用defineProperty。事实上,我仍然在我的回答中使用它,我从未说过你应该省略它。我仍然不明白我的答案有什么问题。除此之外,我错误地认为你写了return "John" 是个错误,它成功地修改了你想要的 Animal 的属性,或者不是?你试过小提琴吗?
【解决方案2】:

使属性可配置:

function Animal() {
  Object.defineProperty(this, "name", {
    configurable: true,
    set: function(n) {  },
    get: function() { return "Jim"; } // hard-coded to demonstrate problem
  });
}

Monster.prototype = new Animal();

var monster = new Monster();
Object.defineProperty(monster, 'name', {writable: true})
monster.name = "John";
monster.name

【讨论】:

  • 这不可能在我的例子中,但它确实解决了阴影问题。
【解决方案3】:

我不完全确定您期望它如何工作。毕竟,你的 setter 什么都不做,你的 getter 返回一个常量。

为什么不这样做呢?

function Animal() {
    this.name = "Jim";
}

那么你可以这样做:

var monster = new Monster();
monster.name = "John";
monster.name // John

【讨论】:

  • “能够知道何时设置/更改属性”
  • 这是一个人为的示例,用于演示如何不正确地对属性进行阴影。缺乏属性阴影是我遇到的问题。我需要使用定义,因为我需要监听属性的变化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-27
  • 2022-10-14
  • 1970-01-01
  • 2012-01-24
  • 2019-07-12
  • 2015-08-07
  • 1970-01-01
相关资源
最近更新 更多