Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Javascript的继承类中声明getter/setter_Javascript_Oop_Encapsulation_Getter Setter - Fatal编程技术网

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

在Javascript的继承类中声明getter/setter,javascript,oop,encapsulation,getter-setter,Javascript,Oop,Encapsulation,Getter Setter,我熟悉强类型OOP语言,比如C#和Java,所以我对Javascript有点困惑。我希望封装我的类,例如: function Human() { var _name = ''; var _nameChangeCounter = 0; } Human.constructor = Human; Human.prototype = Object.create(Animal); 如您所见,Human扩展了Animal类。现在我需要一个用于名称的getter和setter,以及一个用于

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

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

Human.constructor = Human;
Human.prototype = Object.create(Animal);
如您所见,
Human
扩展了
Animal
类。现在我需要一个用于
名称
的getter和setter,以及一个用于
名称更改计数器
的getter。在
名称
的设置器中,应增加
名称更改计数器
。我在中查看了如何使用Javascript制作getter和setter:


然而,既然原型是继承的,我该怎么做呢?我是否必须使用Java风格(创建
getName
setName
getNameChangeCounter
函数)?像
window.location.href
这样的属性是如何实现的?

在mdn上找到了这个函数:

下面是一个小提琴的例子:

下面是一些使用Object.defineProperties的getter和setter javascript

Object.defineProperties(Person.prototype, {
    "name": {
        get: function() { return this._name },
        set: function(name) { 
            this.changeCount++
            this._name = name
        }
    }
})
这对我很有用:

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

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

要创建从动物继承的对象,请执行以下操作:

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._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()时设置方法,则可以使用。但遗憾的是,该语法过于冗长。

窗口是一个宿主对象,它是设置的,但实现希望设置它。它不一定(甚至可能)使用构造函数进行设置。它类似于内置的对象,比如数学或日期,你可以看看和免费的书。我发现它们信息丰富,很有帮助。不要把DOM和JS搞混了。。。它们是不同的东西。。。DOM有很多“本地代码”。
Human.prototype=Object.create(Animal)
不是好的形式。create(Animal)已返回原型设置为Animal的对象。您已使用Human.prototype.prototype==Animal创建了一个2长的原型链。原型是指一个空的物体,其原型指向动物。你所需要的就是Human=Object.create(Animal)。这对我来说很有用,VisualStudio的Intellisense甚至可以重新调整属性!
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