rogerxu / rogerxu.github.io

Roger Xu's Blog
3 stars 2 forks source link

Prototype #68

Open rogerxu opened 7 years ago

rogerxu commented 7 years ago

Inheritance and the prototype chain - JavaScript | MDN

Inheritance in JavaScript - Learn web development | MDN

rogerxu commented 7 years ago

Class vs Prototypal Inheritance

Master the JavaScript Interview: What’s the Difference Between Class & Prototypal Inheritance? – JavaScript Scene – Medium

Class Inheritance

Classes inherit from classes and create subclass relationships: hierarchical class taxonomies.

class Foo {}
typeof Foo // 'function'

JavaScript’s class inheritance uses the prototype chain to wire the child Constructor.prototype to the parent Constructor.prototype for delegation. Usually, the super() constructor is also called. Those steps form single-ancestor parent/child hierarchies and create the tightest coupling available in OO design.

class ColorPoint extends Point {
}

// 等同于
class ColorPoint extends Point {
  constructor(...args) {
    super(...args);
  }
}

Prototypal Inheritance

A prototype is a working object instance. Objects inherit directly from other objects.

Concatenative inheritance

The process of inheriting features directly from one object to another by copying the source objects properties. In JavaScript, source prototypes are commonly referred to as mixins. Since ES6, this feature has a convenience utility in JavaScript called Object.assign(). Prior to ES6, this was commonly done with Underscore/Lodash’s .extend() jQuery’s $.extend().

Prototype delegation

In JavaScript, an object may have a link to a prototype for delegation. If a property is not found on the object, the lookup is delegated to the delegate prototype, which may have a link to its own delegate prototype, and so on up the chain until you arrive at Object.prototype, which is the root delegate. This is the prototype that gets hooked up when you attach to a Constructor.prototype and instantiate with new. You can also use Object.create() for this purpose, and even mix this technique with concatenation in order to flatten multiple prototypes to a single delegate, or extend the object instance after creation.

// subclass extends superclass
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;

var cat1 = new Cat();

任何一个prototype对象都有一个constructor属性,指向它的构造函数。如果没有"Cat.prototype = Object.create(Animal.prototype);"这一行,Cat.prototype.constructor是指向Cat的;加了这一行以后,Cat.prototype.constructor指向Animal。

console.log(Cat.prototype.constructor == Animal); //true

更重要的是,每一个实例也有一个constructor属性,默认调用prototype对象的constructor属性。

console.log(cat1.constructor == Cat.prototype.constructor); // true

因此,在运行"Cat.prototype = new Animal();"这一行之后,cat1.constructor也指向Animal!

console.log(cat1.constructor == Animal); // true

这显然会导致继承链的紊乱(cat1明明是用构造函数Cat生成的),因此我们必须手动纠正,将Cat.prototype对象的constructor值改为Cat。

Functional inheritance

In JavaScript, any function can create an object. When that function is not a constructor (or class), it’s called a factory function. Functional inheritance works by producing an object from a factory, and extending the produced object by assigning properties to it directly (using concatenative inheritance). Douglas Crockford coined the term, but functional inheritance has been in common use in JavaScript for a long time.

rogerxu commented 6 years ago

Object.create()

Object.create() - JavaScript | MDN

const prototype = Object.create(Parent.prototype);
prototype.constructor = Child;
Child.prototype = prototype;

let child = new Child();
rogerxu commented 6 years ago

Prototype

function Parent(name) {
  this.name = name;
  this.items = [];
}

Parent.prototype.getName = function() {
  return this.name;
};

function Child(name, age) {
  Parent.call(this, name);
  this.age = age;
}

Child.prototype = new Father(); // OK?
Child.prototype.constructor = Child;
Child.prototype.doSomething = function() {
  console.log(this.age);
};

let child = new Child('foo', 23);
rogerxu commented 6 years ago

Prototype | JS | InterviewMap

https://camo.githubusercontent.com/71cab2efcf6fb8401a2f0ef49443dd94bffc1373/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031382f332f31332f313632316538613962636230383732643f773d34383826683d35393026663d706e6726733d313531373232 image