Javascript继承:调用超级构造函数还是使用原型链? [英] Javascript inheritance: call super-constructor or use prototype chain?

查看:129
本文介绍了Javascript继承:调用超级构造函数还是使用原型链?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我读到了MDC中的JavaScript调用用法

Quite recently I read about JavaScript call usage in MDC

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call

下面显示的示例中的一个linke,我仍然不明白。

one linke of the example shown below, I still don't understand.

为什么他们这样使用继承

Why are they using inheritance here like this

Prod_dept.prototype = new Product();

这是必要的吗?因为有超级构造函数的调用

is this necessary? Because there is a call to the super-constructor in

Prod_dept()

无论如何,像这样

Product.call

这是不是常见的行为?何时使用超级构造函数调用或使用原型链更好?

is this just out of common behaviour? When is it better to use call for the super-constructor or use the prototype chain?

function Product(name, value){
  this.name = name;
  if(value >= 1000)
    this.value = 999;
  else
    this.value = value;
}

function Prod_dept(name, value, dept){
  this.dept = dept;
  Product.call(this, name, value);
}

Prod_dept.prototype = new Product();

// since 5 is less than 1000, value is set
cheese = new Prod_dept("feta", 5, "food");

// since 5000 is above 1000, value will be 999
car = new Prod_dept("honda", 5000, "auto");

感谢让事情更清楚

推荐答案

真正问题的答案是你需要同时做到这两点:

The answer to the real question is that you need to do both:


  • 将原型设置为父实例初始化原型链(继承),这只做一次(因为原型对象是共享的)。

  • 调用父的构造函数初始化对象本身,这是通过每个实例化(每次构造时都可以传递不同的参数)。

因此,在设置时不应该调用父的构造函数遗产。仅在实例化从另一个继承的对象时。

Therefore, you should not call the parent's constructor when setting up inheritance. Only when instantiating an object that inherits from another.

Chris Morgan的答案几乎完成,缺少一个小细节(构造函数属性)。让我建议一种设置继承的方法。

Chris Morgan's answer is almost complete, missing a small detail (constructor property). Let me suggest a method to setup inheritance.

function extend(base, sub) {
  // Avoid instantiating the base class just to setup inheritance
  // Also, do a recursive merge of two prototypes, so we don't overwrite 
  // the existing prototype, but still maintain the inheritance chain
  // Thanks to @ccnokes
  var origProto = sub.prototype;
  sub.prototype = Object.create(base.prototype);
  for (var key in origProto)  {
     sub.prototype[key] = origProto[key];
  }
  // The constructor property was set wrong, let's fix it
  Object.defineProperty(sub.prototype, 'constructor', { 
    enumerable: false, 
    value: sub 
  });
}

// Let's try this
function Animal(name) {
  this.name = name;
}

Animal.prototype = {
  sayMyName: function() {
    console.log(this.getWordsToSay() + " " + this.name);
  },
  getWordsToSay: function() {
    // Abstract
  }
}

function Dog(name) {
  // Call the parent's constructor
  Animal.call(this, name);
}

Dog.prototype = {
    getWordsToSay: function(){
      return "Ruff Ruff";
    }
}    

// Setup the prototype chain the right way
extend(Animal, Dog);

// Here is where the Dog (and Animal) constructors are called
var dog = new Dog("Lassie");
dog.sayMyName(); // Outputs Ruff Ruff Lassie
console.log(dog instanceof Animal); // true
console.log(dog.constructor); // Dog

在创建类时,请查看我的博客文章,了解更多的语法糖。 http://js-bits.blogspot.com/2010 /08/javascript-inheritance-done-right.html

See my blog post for even further syntactic sugar when creating classes. http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

从Ext-JS复制的技术和 http://www.uselesspickles.com/class_library/ 以及来自 https://stackoverflow.com/users/1397311/ccnokes

Technique copied from Ext-JS and http://www.uselesspickles.com/class_library/ and a comment from https://stackoverflow.com/users/1397311/ccnokes

这篇关于Javascript继承:调用超级构造函数还是使用原型链?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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