【问题标题】:How to use getters and setters in Javascript如何在 Javascript 中使用 getter 和 setter
【发布时间】:2014-03-02 14:58:20
【问题描述】:

谁能解释一下为什么这段简单的代码不起作用?

var user = {
    get name() {
        return this.name;
    },    
    set name(value) {
        this.name = value;
    }
};
user.name = 'David';

当我把它放在 Firefox 21.0 的 Firebug 控制台中时,它给了我这个错误:

InternalError: too much recursion
this.name = value;

为什么?在 Javascript 中定义 getter 和 setter 的正确方法是什么?

【问题讨论】:

  • 您无限递归地调用 name(),因此出现错误“递归过多”
  • 问题是你试图在你的设置器中设置一个名为“name”的属性。那会做什么?它会调用setter,它会尝试设置一个名为“name”的属性。那会做什么? ...
  • 问题是this.name = value;触发了函数set name(value),它设置了this.name = value;,又触发了set name(value)函数……我可以继续。
  • @StephenKennedy 它们确实作为原生功能存在。再加上你的评论离题了。

标签: javascript oop


【解决方案1】:

当您尝试设置name 时,该函数将设置this.name = value

但该函数现在正尝试设置name。因此它将再次调用该函数并将this.name设置为value

但该函数现在正尝试设置name。因此它将再次调用该函数并将this.name设置为value

但该函数现在正试图设置name。因此它将再次调用该函数并将this.name设置为value

....... 稍后.......

但该函数现在正尝试设置name。因此它将再次调用该函数并将this.name设置为value

但是浏览器已经确定调用堆栈太深,函数调用自身的次数太多,因此为了防止完全崩溃,它会导致函数失败并出现您看到的错误。


尝试使用不同的属性名称,例如this._name,来存储和检索值。

【讨论】:

  • 你一定喜欢递归。感谢上帝,这在 Lua 中是不可能的。否则你将有一个永远不会抛出错误的无限循环。尾调用优化 FTW。
  • 我称这里为 Vicious Möbius Strip。这就像一个恶性循环,但只有一方面;)
  • 更像是恶性环形阵列。你从一侧出来,到另一侧结束,并继续这样做,直到你最终意识到你在兜圈子并放弃。
  • 所以 Javascript 的 getter 和 setter 的行为不像 PHP 中的“魔术” setter (__set) 和 getter (__get) 方法?那里没有递归问题。见this
【解决方案2】:

你的 setter 正在调用自己。

这是一个解决方案:

var user = {
    get name() {
        return this._name;
    },    
    set name(value) {
        this._name = value;
    }
};
user.name = 'David';

附注:注意getset 运算符在 IE8 中不受支持。

【讨论】:

【解决方案3】:

试试,

var user = {
    get name() {
        return this._name;
    },    
    set name(value) {
        this._name = value;
    }
};
user.name = 'David';

注意使用_name 而不是name。在name 的setter 中设置name 的值是递归调用,因此例外。

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 2017-07-09
    • 1970-01-01
    • 2015-05-01
    相关资源
    最近更新 更多