2016 년 10 월 수정 :이 질문은 2012 년에 요청되었습니다. 매달 누군가가 답변을 반박하는 새로운 답변이나 댓글을 추가하지만 질문이 오래되었을 수 있으므로 그렇게하는 것이 의미가 없습니다. Gnome Javascript 가 브라우저 항목이 아닌 그놈 쉘 확장을 작성 하는 것이 었습니다 .
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.
내 질문은 이 구문을 사용하여 프로토 타입에서 setter / getter를 어떻게 정의합니까?
나는 그것을 하고는했다:
Subclass.prototype = {
__proto__: Superclass.prototype,
/* other methods here ... */
get myProperty() {
// code.
}
}
그러나 분명히 다음은 작동하지 않습니다.
Subclass.prototype.get myProperty() { /* code */ }
저는 GJS (GNOME Javascript)를 사용하고 있으며 엔진은 Mozilla Spidermonkey와 거의 동일합니다. 내 코드는 GJS에서 지원하는 한 브라우저 용이 아닙니다 (Spidermonkey를 의미합니까?). 교차 호환이되지 않아도 상관 없습니다.
답변
객체 리터럴 선언 사용 (가장 간단한 방법) :
var o = {
a: 7,
get b() {
return this.a + 1;
},
set c(x) {
this.a = x / 2
}
};
사용 Object.defineProperty
(ES5를 지원하는 최신 브라우저에서) :
Object.defineProperty(o, "myProperty", {
get: function myProperty() {
// code
}
});
또는 __defineGetter__
및 사용 __defineSetter__
( DEPRECATED ) :
var d = Date.prototype;
d.__defineGetter__("year", function() { return this.getFullYear(); });
d.__defineSetter__("year", function(y) { this.setFullYear(y); });
답변
사용 Object.defineProperty()
에 Subclass.prototype
. 이 또한 __defineGetter__
및 __defineSetter__
일부 브라우저에서 사용할 수 있지만,이되지 않습니다. 귀하의 예를 들면 다음과 같습니다.
Object.defineProperty(Subclass.prototype, "myProperty", {
get: function myProperty() {
// code
}
});
답변
나는 당신이 이렇게하고 싶었다고 생각합니다.
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
답변
setter와 getter를 “객체의 프로토 타입 내부에”정의하려면 다음과 같이해야합니다.
Object.defineProperties(obj.__proto__, {"property_name": {get: getfn, set: setfn}})
유틸리티 함수로 단축 할 수 있습니다.
//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);
여기서는 prop.apply를 사용하여 Product.prototype을 호출 할 때 컨텍스트를 “this”로 설정합니다.
이 코드를 사용하면 질문에서 물었 듯이 인스턴스가 아닌 객체의 프로토 타입 내부에서 get / set 속성으로 끝납니다.
(테스트 된 Firefox 42, Chrome 45)
답변
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;
}());
Object.defineProperty ()를 사용하면 속성 정의를 더 잘 제어 할 수 있습니다. 예를 들어, 설명하는 속성을 동적으로 삭제하거나 재정의 할 수 있는지, 값을 변경할 수 있는지 등을 지정할 수 있습니다.
설명자 객체의 다음 속성을 설정하여 이러한 제약을 적용 할 수 있습니다.
- 쓰기 가능 : 속성 값을 변경할 수 있는지 여부를 나타내는 부울입니다. 기본값은 false입니다.
- configurable : 속성의 설명자를 변경할 수 있는지 또는 속성 자체를 삭제할 수 있는지 여부를 나타내는 부울입니다. 기본값은 false입니다.
- enumerable : 객체의 속성에 대한 루프에서 속성에 액세스 할 수 있는지 여부를 나타내는 부울입니다. 기본값은 false입니다.
- value : 속성과 관련된 값을 나타냅니다. 기본값은 정의되지 않음
답변
다음 은 getter 와 setter 가있는 간단한 Animal → Dog
상속의 예입니다 .Animal
//////////////////////////////////////////
// General Animal constructor
function Animal({age, name}) {
// if-statements prevent triggering the setter on initialization
if(name) this.name = name
if(age) this.age = age
}
// an alias "age" must be used, so the setter & getter can use an
// alternative variable, to avoid using "this.age", which will cause
// a stack overflow of "infinite" call stack when setting the value.
Object.defineProperty(Animal.prototype, "age", {
get(){
console.log("Get age:", this.name, this._age) // getting
return this._age
},
set(value){
this._age = value
console.log("Set age:", this.name, this._age) // setting
}
})
//////////////////////////////////////////
// Specific Animal (Dog) constructor
function Dog({age = 0, name = 'dog'}) {
this.name = name
this.age = age
}
// first, defined inheritance
Dog.prototype = new Animal({});
// add whatever additional methods to the prototype of Dog
Object.assign(Dog.prototype, {
bark(woff){
console.log(woff)
}
})
//////////////////////////////////////////
// Instanciating
var koko = new Animal({age:300, name:'koko'})
var dog1 = new Dog({age:1, name:'blacky'})
var dog2 = new Dog({age:5, name:'shorty'})
console.log(dog1)
koko.age
dog1.age = 3;
dog1.age
dog2.age