在 Javascript 中创建类 getter/setter 的最佳方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/4450941/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to create class getter/setters in Javascript?
提问by Edward Tanguay
Coming from C#/PHP, I would like to have full getters/setters on the classes (functions) that I create with Javascript.
来自 C#/PHP,我希望在我使用 Javascript 创建的类(函数)上拥有完整的 getter/setter。
However, in much of the Javascript code I have encountered, getters and setters are not used, rather simple public variables.
然而,在我遇到的大部分 Javascript 代码中,并没有使用 getter 和 setter,而是使用简单的公共变量。
I was pleased to find John Resig's articleon getters and setters, but some comments on it which state that some browsers "do not support getters and setters" which is confusing to me since they are not a "feature" of Javascript but more of a simple pattern which uses basic Javascript syntax. This article was also written in 2007 so it could be outdated by now.
我很高兴找到John Resig关于 getter 和 setter的文章,但对它的一些评论指出某些浏览器“不支持 getter 和 setter”,这让我感到困惑,因为它们不是 Javascript 的“功能”,而是更多使用基本 Javascript 语法的简单模式。这篇文章也是 2007 年写的,所以现在可能已经过时了。
What is the current state of getters and setters in Javascript?Are they indeed "supported" by all browsers today (whatever that means)? Are they a useful programming pattern for Javascript or are Javascript classes (being functions) better off with public variables? Is there a better way to implement them than the following?
Javascript 中 getter 和 setter 的当前状态是什么?今天所有浏览器确实“支持”它们(无论这意味着什么)?它们是一种有用的 Javascript 编程模式还是 Javascript 类(作为函数)使用公共变量更好?有没有比以下更好的方法来实现它们?
$(document).ready(function() {
    var module = new Module('idcode');
    module.set_id_code('new idcode');
    module.set_title('new title');
    $('body').html(module.get_id_code()+': '+module.get_title());
});
function Module(id_code, title) {
    var id_code = id_code;
    var title = title;
    //id_code
    this.get_id_code = function() {
        return id_code;
    }
    this.set_id_code = function(value) {
        id_code = value;
    }
    //title
    this.get_title = function() {
        return title;
    }
    this.set_title = function(value) {
        title = value;
    }
}
回答by Tim Down
Firefox, Safari, Chrome and Opera (but not IE) all have the same non-standard getterand settermechanism built in. ECMAScript 5 includes a different syntax that is currently making its way into browsersand will become the standard in future. IE 8 already has this feature, but only on DOM nodes, not regular native JavaScript objects. This is what the syntax looks like:
Firefox、Safari、Chrome 和 Opera(但不是 IE)都内置了相同的非标准getter和setter机制。ECMAScript 5 包含一种不同的语法,目前正在进入浏览器并将成为未来的标准。IE 8 已经有这个功能,但仅限于 DOM 节点,而不是常规的原生 JavaScript 对象。语法如下所示:
var obj = {};
Object.defineProperty(obj, "value", {
    get: function () {
        return this.val;
    },
    set: function(val) {
        this.val = val;
    }
});
回答by Jason S
You're missing the point, I think. (Or maybe the other answerers are missing the point.) ECMAScript provides a "behind-the-scenes" getter/setter mechanism, so that
你没有抓住重点,我想。(或者其他回答者可能没有抓住重点。)ECMAScript 提供了“幕后”getter/setter 机制,以便
x.foo = 3;
y = x.foo;
really translates into (sort of)
真的翻译成(有点)
x.PutValue("foo",3);
y = x.GetValue("foo");
where PutValueand GetValueare unnamed, not directly accessible functions for setters and getters for properties. (See the ECMAScript standard, 3rd ed., section 8.7.1. and 8.7.2) The 3rd edition doesn't seem to explicitly define how users can set up custom getters and setter functions. Mozilla's implementation of Javascript did and still does, e.g. (this is in JSDBwhich uses Javascript 1.8):
wherePutValue和GetValue是未命名的,不能直接访问属性的 setter 和 getter 函数。(请参阅ECMAScript 标准,第 3 版,第 8.7.1. 和 8.7.2 节)第 3 版似乎没有明确定义用户如何设置自定义 getter 和 setter 函数。Mozilla 的 Javascript 实现确实并且仍然如此,例如(这是在使用 Javascript 1.8 的JSDB中):
js>x = {counter: 0};
[object Object]
js>x.__defineGetter__("foo", function() {return this.counter++; });
js>x.foo
0
js>x.foo
1
js>x.foo
2
js>x.foo
3
js>x.foo
4
The syntax is (or at least has been so far) browser-specific. Internet Explorer in particular is lacking, at least according to this SO question.
语法是(或至少到目前为止)特定于浏览器的。尤其缺乏 Internet Explorer,至少根据这个 SO question。
The 5th edition of the ECMAScript standard does seem to standardize on this mechanism. See this SO question on getters and setters.
ECMAScript 标准的第 5 版似乎对这种机制进行了标准化。请参阅有关 getter 和 setter 的 SO 问题。
edit: A more practical example, perhaps, for your purposes:
编辑:一个更实际的例子,也许,为了你的目的:
function makePrivateObject()
{
   var state = 0;
   var out = {};
   out.__defineSetter__("foo", function(x) {});
   // prevent foo from being assigned directly
   out.__defineGetter__("foo", function() { return state; });
   out.count = function() { return state++; }
   return out;
}
js>x = makePrivateObject()
[object Object]
js>x.foo
0
js>x.foo = 33
33
js>x.foo
0
js>x.count()
0
js>x.count()
1
js>x.count()
2
js>x.foo
3
回答by sje397
How about:
怎么样:
function Module(id_code, title) {
    var id_code = id_code;
    var title = title;
    var privateProps = {};
    this.setProperty = function(name, value) {
      // here you could e.g. log something
      privateProps[name] = value;
    }
    this.getProperty = function(name) {
      return privateProps[name];
    }
}
The getter and setter methods here act on a private object used to store properties that cannot be accessed from any other methods. So you could, for example, implement a setter (or getter) that logs or does ajax or whatever, whenever a property is modified (one of the purposes of getter/setter methods).
这里的 getter 和 setter 方法作用于一个私有对象,用于存储无法从任何其他方法访问的属性。因此,例如,您可以实现一个 setter(或 getter),它在修改属性时记录或执行 ajax 或其他任何操作(getter/setter 方法的目的之一)。
回答by PuercoPop
You can actually define setters and getters in javascript and not just mimick them. I think it works on every browser except IE8 and below.
您实际上可以在 javascript 中定义 setter 和 getter,而不仅仅是模仿它们。我认为它适用于除 IE8 及以下的所有浏览器。
$(document).ready(function() {
  var module = new Module('idcode');
  module.id = 'new idcode';
  module.title = 'new title';
  $('body').html(module.id + ': ' + module.title);
});
function Module(id, title) {
  return {
    id_code: id_code,
    _title: title,
    get id() {
      return id_code;
    },
    set id(value) {
      id_code = value;
    },
    get title() {
      return _title;
    },
    set title(value) {
      title = value;
    }
  }
};
回答by jaegow
I like this :
我喜欢这个 :
//  Module
var Module = function() {
    // prive getter/setter value
    var __value;
    // private getter/setter method
    var _value = function() {
        if(!arguments.length) return __value;
        else __value = arguments[0];
    };
    // output/public     
    return {
        value: _value
    };
}
回答by darioo
Getters and setters aren't features, but "design patterns" (code bloat in this case) for languages that don't support property syntax.
Getter 和 setter 不是特性,而是不支持属性语法的语言的“设计模式”(在这种情况下是代码膨胀)。
Since Javascript doesn't need getters and setters, you don't want to write them. Use the language features that are available to you and idioms that work great in one languages don't work so well in another.
由于 Javascript 不需要 getter 和 setter,因此您不想编写它们。使用您可以使用的语言功能,而在一种语言中效果很好的习语在另一种语言中效果不佳。
One of my favorite quotes comes from Python's community:
我最喜欢的引用之一来自 Python 社区:
We're all consenting adults here
我们这里都是大人同意的
when discussing why private variables and information hiding isn't needed.
在讨论为什么不需要私有变量和信息隐藏时。
The quote can be found here.
报价可以在这里找到。
Learn what the language offers you and embrace its culture and rules.
了解该语言为您提供什么并接受其文化和规则。
回答by Supuhstar
One reliable, semantic way I've favored is to use settersand getters. For example, I created the following object:
我喜欢的一种可靠的语义方式是使用setter和getter。例如,我创建了以下对象:
var myComplexObject = {
  changelog: {},
  log: function(name, val) {
    console.log("set " + name + " to " + val);
    if (!this.changelog[name])
      this.changelog[name] = [];
    this.changelog[name].push(val);
  },
  set o (val) {
    this.log("o", val);
  },
  get o () {
    console.log("You will never know the true value!");
    return 42;
  }
}
In here, whenever you read or modify the value of o, the behavior is customized. Take, for example, the following line of code and its console output:
在这里,每当您读取或修改 的值时o,行为都是自定义的。以以下代码行及其控制台输出为例:
myComplexObject.o = "oxygen";
set o to oxygen
Then, in this example, attempting to read the value results in this:
然后,在此示例中,尝试读取该值会导致:
var read = myComplexObject.o;
console.log(read);
You will never know the true value!
42
And, in this example, each new value you set is logged:
并且,在本例中,您设置的每个新值都会被记录:
myComplexObject.o = "Oh no!";
console.log(myComplexObject.changelog.o);
set o to Oh no!
["oxygen", "Oh no!"]

