Javascript继承:在设置原型时调用Object.create [英] Javascript inheritance: calling Object.create when setting a prototype

查看:113
本文介绍了Javascript继承:在设置原型时调用Object.create的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习面向对象的Javascript的一些方面。我遇到了这个片段

I'm learning some aspects of Object-oriented Javascript. I came across this snippet

var Person = function(firstName, lastName)
{
  this.lastName = lastName;
  this.firstName = firstName;
};

Object.defineProperties(Person.prototype, {
  sayHi: {
    value: function() {
      return "Hi my name is " + this.firstName;
    }
  },
  fullName: {
    get: function() {
      return this.firstName + " " + this.lastName;
    }
  }
});

var Employee = function(firstName, lastName, position) {
  Person.call(this, firstName, lastName);
  this.position = position;
};

Employee.prototype = Object.create(Person.prototype);

var john = new Employee("John", "Doe", "Dev");

我的问题是:为什么这个代码片段使用
Object.create(Person.prototype )?我们不应该简单地重置原型:

And my question is: why does this snippet use Object.create(Person.prototype)? Shouldn't we simply reset prototype with:

Employee.prototype = Person.prototype;


推荐答案

做Employee.prototype = Person.prototype就像说员工是人而不是员工是人。对原型的任何更改都将反映在两个类中。

Doing Employee.prototype = Person.prototype is like saying "Employee is Person" rather than "Employee is a Person." Any changes to either prototype will be reflected in both classes.

这是一个示范。显然,我们不希望我们的人员工作,因为他们没有职位。

Here's a demonstration. Obviously we don't want our Persons working because they don't have a position.

因此,没有Object.create设置原型链的正确方法是:

So the right way to setup the prototype chain without Object.create is:

Employee.prototype = new Person;

但这需要实例化一个对象,这有点时髦 - 特别是如果你不想要要调用的人的构造函数。无论您是否想要这样,所有Employee实例都将继承未定义的firstName和lastName属性。

But this requires instantiating an object, which is a little funky -- especially if you don't want Person's constructor to be called. All of your Employee instances are going to inherit undefined "firstName" and "lastName" properties, regardless of whether you wanted that.

在这种情况下,它没什么大不了的 - Employee构造函数将自己设置这些属性,这将取代从Person继承的属性。但请考虑此示例。有人可能会认为freeTime是Person的实例级属性,因为它不在原型上,所以不会被复制。另外,我们从未从Employee调用Person构造函数。不是这样 - 在Employee原型上设置了 ,因为我们必须实例化一个对象。

In this case it's no big deal -- the Employee constructor is going to set those properties on itself which will supersede the properties inherited from Person. But consider this example. One might think that freeTime is an instance level property for Person that will not be copied because it's not on the prototype. Plus, we never called the Person constructor from Employee. Not so -- freeTime was set on the Employee prototype because we had to instantiate an object.

所以你可以做的最好和最干净的继承是通过Object.create。如果要调用父类的构造函数,可以在子类的构造函数中显式地执行此操作。另一个好处是Object.create有一个defineProperties的第二个(可选)参数。所以你也可以这样做:

So the best and cleanest inheritance you can do is through Object.create. If you want to call the parent class' constructor, you can do so explicitly from within the subclass' constructor. Another nice thing is that Object.create has a second (optional) argument to defineProperties. So you can also do this:

Employee.prototype = Object.create(Person.prototype, {
  work: {
    value: function() {
      return this.fullName+" is doing some "+this.position+" stuff");  
    }
  }
});

当然,如果您必须支持旧版浏览器,则无法使用Object.create。另一种方法是使用下划线或lodash等库中的clone / extend。或者是这个小舞蹈:

Of course, if you have to support legacy browsers you can't use Object.create. The alternative is to use clone / extend from libraries like underscore or lodash. Or there's this little dance:

var subclass = function() { };
subclass.prototype = Person.prototype;
Employee.prototype = new subclass;

这篇关于Javascript继承:在设置原型时调用Object.create的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆