Javascript 如何在原型上定义 setter/getter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10592753/
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
How to define setter/getter on prototype
提问by mathematical.coffee
EDIT Oct 2016: Please note this question was asked in 2012. Every month or so someone adds a new answer or comment that refutes an answer, but doesn't really make sense to do so as the question is probably out of date (remember, it was for Gnome Javascriptto write gnome-shell extensions, not browser stuff, which is quite specific).
编辑 2016 年 10 月:请注意这个问题是在 2012 年提出的。每个月左右,有人会添加一个新的答案或评论来反驳答案,但这样做没有意义,因为这个问题可能已经过时了(请记住,是Gnome Javascript编写 gnome-shell 扩展,而不是浏览器的东西,这是非常具体的)。
Following my previous questionon how to do subclassing in Javascript, I'm making a subclass of a superclass like so:
按照我之前关于如何在 Javascript 中进行子类化的问题,我正在创建一个超类的子类,如下所示:
function inherits(Child,Parent) {
var Tmp = function {};
Tmp.prototype = Parent.prototype;
Child.prototype = new Tmp();
Child.prototype.constructor = Child;
}
/* Define subclass */
function Subclass() {
Superclass.apply(this,arguments);
/* other initialisation */
}
/* Set up inheritance */
inherits(Subclass,Superclass);
/* Add other methods */
Subclass.prototype.method1 = function ... // and so on.
My question is, how do I define a setter/getter on the prototype with this syntax?
我的问题是,如何使用此语法在原型上定义 setter/getter?
I used to do:
我曾经做过:
Subclass.prototype = {
__proto__: Superclass.prototype,
/* other methods here ... */
get myProperty() {
// code.
}
}
But obviously the following won't work:
但显然以下方法是行不通的:
Subclass.prototype.get myProperty() { /* code */ }
I'm using GJS (GNOME Javascript), and the engine is meant to be the more-or-less same as the Mozilla Spidermonkey one. My code is not intended for a browser so as long as it's supported by GJS (I guess that means Spidermonkey?), I don't mind if it's not cross-compatible.
我正在使用 GJS(GNOME Javascript),并且该引擎或多或少与 Mozilla Spidermonkey 相同。我的代码不适用于浏览器,只要 GJS 支持它(我猜这意味着 Spidermonkey?),我不介意它是否不交叉兼容。
采纳答案by bfavaretto
Using an object literal declaration (simplest way):
使用对象字面量声明(最简单的方法):
var o = {
a: 7,
get b() {
return this.a + 1;
},
set c(x) {
this.a = x / 2
}
};
Using Object.defineProperty
(on modern browsers that support ES5):
使用Object.defineProperty
(在支持 ES5 的现代浏览器上):
Object.defineProperty(o, "myProperty", {
get: function myProperty() {
// code
}
});
Or using __defineGetter__
and __defineSetter__
(DEPRECATED):
或使用__defineGetter__
和__defineSetter__
(已弃用):
var d = Date.prototype;
d.__defineGetter__("year", function() { return this.getFullYear(); });
d.__defineSetter__("year", function(y) { this.setFullYear(y); });
回答by Bergi
Use Object.defineProperty()
on Subclass.prototype
. There are also __defineGetter__
and __defineSetter__
available on some browsers, but they are deprecated. For your example, it would be:
使用Object.defineProperty()
上Subclass.prototype
。在某些浏览器上也有__defineGetter__
并且__defineSetter__
可用,但它们已被弃用。对于您的示例,它将是:
Object.defineProperty(Subclass.prototype, "myProperty", {
get: function myProperty() {
// code
}
});
回答by Павел Щеголев
I think you wanted to do this way:
我想你想这样做:
function Unit() {
this._data; // just temp value
}
Unit.prototype = {
get accreation() {
return this._data;
},
set accreation(value) {
this._data = value
},
}
Unit.prototype.edit = function(data) {
this.accreation = data; // setting
this.out();
};
Unit.prototype.out = function() {
alert(this.accreation); // getting
};
var unit = new Unit();
unit.edit('setting and getting');
function Field() {
// children
}
Field.prototype = Object.create(Unit.prototype);
Field.prototype.add = function(data) {
this.accreation = data; // setting
this.out();
}
var field1 = new Field();
field1.add('new value for getter&setter');
var field2 = new Field();
field2.out();// because field2 object has no setting
回答by Mackraken
To define setters and getters "inside the object's prototype" you have to do something like this:
要在“对象原型内”定义 setter 和 getter,您必须执行以下操作:
Object.defineProperties(obj.__proto__, {"property_name": {get: getfn, set: setfn}})
You can short that down with an utility function:
你可以用一个效用函数来缩短它:
//creates get/set properties inside an object's proto
function prop (propname, getfn, setfn) {
var obj = {};
obj[propname] = { get: getfn, set: setfn };
Object.defineProperties(this, obj);
}
function Product () {
this.name = "Product";
this.amount = 10;
this.price = 1;
this.discount = 0;
}
//how to use prop function
prop.apply(Product.prototype, ["total", function(){ return this.amount * this.price}]);
pr = new Product();
console.log(pr.total);
Here we use prop.apply to set the context Product.prototype as "this" when we call it.
这里我们使用 prop.apply 将上下文 Product.prototype 设置为“this”。
With this code you end with a get/set property inside the object's prototype, not the instance, as the question asked.
使用此代码,您以对象原型内的 get/set 属性结束,而不是如问题所问的实例。
(Tested Firefox 42, Chrome 45)
(已测试 Firefox 42、Chrome 45)
回答by Michael Horojanski
Specify a getter or a setter in constructors by Object.defineProperty() method. This method takes three arguments: the first argument is the object to add the property to, the second is the name of the property, and the third is the property's descriptor. For instance, we can define the constructor for our person object as follows:
通过 Object.defineProperty() 方法在构造函数中指定 getter 或 setter。该方法接受三个参数:第一个参数是要添加属性的对象,第二个是属性的名称,第三个是属性的描述符。例如,我们可以为我们的 person 对象定义构造函数,如下所示:
var Employee = (function() {
function EmployeeConstructor() {
this.first = "";
this.last = "";
Object.defineProperty(
this,
"fullName", {
get: function() {
return this.first + " " +
this.last;
},
set: function(value) {
var parts = value.toString().split(" ");
this.name = parts[0] || "";
this.last = parts[1] || "";
}
});
}
return
EmployeeConstructor;
}());
Using Object.defineProperty() gives more control over our property definition. For example, we can specify if the property we are describing can be dynamically deleted or redefined, if its value can be changed, and so on.
使用 Object.defineProperty() 可以更好地控制我们的属性定义。例如,我们可以指定我们所描述的属性是否可以动态删除或重新定义,是否可以更改其值,等等。
We can such constraints by setting the following properties of the descriptor object:
我们可以通过设置描述符对象的以下属性来进行此类约束:
- writable: This is a Boolean that says whether the value of the property can be changed; its default value is false
- configurable: This is a Boolean that says whether the property's descriptor can be changed or the property itself can be deleted; its default value is false
- enumerable: This is a Boolean indicating whether the property can be accessed in a loop over the object's properties; its default value is false
- value: This represents the value associated to the property; its default value is undefined
- writable:这是一个布尔值,表示属性的值是否可以更改;它的默认值为 false
- 可配置:这是一个布尔值,表示是否可以更改属性的描述符或可以删除属性本身;它的默认值为 false
- enumerable:这是一个布尔值,指示是否可以在对象属性的循环中访问该属性;它的默认值为 false
- value:这表示与属性相关的值;它的默认值是未定义的