在Javascript中的继承类中声明getter / setter

时间:2014-05-01 13:35:27

标签: javascript oop encapsulation getter-setter

我熟悉强类型的OOP语言,比如C#和Java,所以我对Javascript有点困惑。我希望我的class被封装,例如:

function Human() {
    var _name = '';
    var _nameChangeCounter = 0;
}

Human.constructor = Human;
Human.prototype = Object.create(Animal);

如您所见,Human扩展了Animal类。现在我需要Name的getter和setter,以及NameChangeCounter的getter。在Name的设置器中,它应该增加NameChangeCounter。我查找了如何在this question中的Javascript中创建getter和setter:

Name.prototype = {
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
};

但是,现在原型被用于继承,我该怎么办呢?我是否必须执行Java风格(创建getNamesetNamegetNameChangeCounter函数)? window.location.href等属性如何实现?

3 个答案:

答案 0 :(得分:3)

这对我有用:

function Name(){
    this.first = '';
    this.last = '';
}

Name.prototype.getFullName = function() {
    return this.first + ' ' + this.last;
}

Name.prototype.setFullName = function(fullName){
    var names = fullName.split(" ");
    this.first = names[0];
    this.last = names[1];
}


function Human() {
    var name = new Name(), 
        counter = 0;
    Object.defineProperty(this, 'name', {
        configurable: true,
        enumerable: true,
        get: function(){
            return name;
        },
        set: function(fullName){
            name.setFullName(fullName);
        }
    });
    Object.defineProperty(this, 'counter', {
        configurable:true,
        enumerable: true,
        get: function(){
            return counter;
        },
        set: function(value){
            counter = value;
        }
    });
}

var luke = new Human();
luke.name = 'Luke Skywalker';

console.log(luke.name.first); //Luke
console.log(luke.name.last); //Skywalker
console.log(luke.name.getFullName()); //Luke Skywalker
console.log(luke.name); //Object

luke.name = 'Peter Parker';
console.log(luke.name.first); //Peter
console.log(luke.name.last); //Parker
console.log(luke.name.getFullName()); //Peter Parker

答案 1 :(得分:1)

在mdn上找到此功能: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Summary

以下是一个示例小提琴:http://jsfiddle.net/EfyCX/1/

这里有一些使用Object.defineProperties

的getter和setter的javascript
Object.defineProperties(Person.prototype, {
    "name": {
        get: function() { return this._name },
        set: function(name) { 
            this.changeCount++
            this._name = name
        }
    }
})

答案 2 :(得分:-2)

您尝试在基于原型的语言中使用经典继承。在javascript中没有类定义和类实例。只有静态对象通过原型链共享方法。

制作从Animal继承的对象:

var Animal = {vertebrae: "jelly"};
var Human = Object.create(Animal)

console.log(Human.vertebrae); //=> jelly

制作从人类继承的对象

var programmer = Object.create(Human);
console.log(programmer.vertebrae); //=> jelly

有些JS机构(主要是Crockford)不鼓励覆盖标准的get和set方法,除非你完全知道自己在做什么。

同样重要的是要注意JS没有私有属性,并且可以通过使用外部函数作用域和闭包来实现该功能。搜索javascript私有属性。

向Human添加方法

Human._name = 'Human';
Human.getName = function(){ return this._name; }
Human.setName = function(val){ this._name = val; }

console.log(programmer.getName()); //=> 'Human'

programmer.setName("Bob");
console.log(programmer.getName()); //=> 'Bob'
console.log(Human.getName()); //=> 'Human'
console.log(Animal.getName()); //=> not a function

如果你想在执行Object.create()时设置方法,可以使用properties object,但遗憾的是这种语法很简洁。