1.创建对象

1. 构造函数模式

  1. function Person(name) {
  2. this.name = name
  3. this.getName = function () {
  4. console.log(this.name)
  5. }
  6. }
  7. var p = new Person()

缺点: 每次创建实例时,每个方法都要被创建一次

2. 原型模式

function Person(name) {
}
Person.prototype.name = 'keivn'
Person.prototype.getName = function () {
        console.log(this.name)
}
var p = new Person()

优点: 方法不会重新创建
缺点: 1.所有的属性和方法都共享

2.原型和原型链

2.继承

父类

function Animal (name) {
  this.name = name
  this.colors = []
}
Animal.prototype.sayName = function() {
  console.log(this.name)
}

1. 原型链继承

function Dog () {
    this.name = 'Dog'
    this.sayName = function() {
        console.log('内部 sayName--->', this.name)
    }
}

Dog.prototype.sayName = function() {
    console.log('prototype -->',  this.name)
}

// 继承父类 Dog.prototype.constructor === Animal
Dog.prototype = new Animal()
Dog.prototype.sayName = function () {
  console.log('Dog sayName')
}
var d1 = new Dog()
d1.colors.push('red') 
var d2 = new Dog()
console.log(d2.colors)

问题:
原型链包含引用值 会在所有的实例间共享
子类有时候需要覆盖父类的方法,或者增加父类没有的方法。为此,这些方法必须在原型赋值之后 再添加到原型上

2.借用构造函数

function Cat () {
    Animal.call(this)
    // Animal.call(this, 'Bar') 继承父类,并传参
}

let c = new Cat()
console.log(c)

子类不能访问父类原型上定义的方法

3.组合继承

function Pets(name, age) {
  Animal.call(this, name)  // 第二次调用Animal
  this.age = age
}
Pets.prototype = new Animal()  // 第一次调用Animal() 

let p = new Pets('pig one', 3)
console.log(p)

组合继承弥补了原型链和盗用构造函数的不足,是JavaScript中使用最多的继承模式。而且组合继承也保留了instanceof操作符和isPrototypeOf()方法识别合成对象的能力

4.原型式继承

ECMAScript 5通过增加Object.create()方法将原型式继承的概念规范化了。

function object(o) { 
  function F() {} 
  F.prototype = o
  return new F()
}

let person = {
  name: 'Greg'
}

let anotherPerson = object(person)

原型式继承非常适合不需要单独创建构造函数

5. 寄生式继承

通过调用函数创建一个新对象

function create(argument) {
  let clone = object(original)
  clone.sayHi = function() { // 以某种方式增强这个对象
    console.log('hi')
  }
  return clone 
}
let person = {
  name: 'Greg'
}
let anotherPerson = createAnother(person)
anotherPerson.sayHi() // 'hi'


6.寄生式组合继承

function inheritPrototype(dog, animal) {
  let prototype = object.create(Animal.prototype)
  prototype.constructor = dog
  dog.prototype = prototype
}

function Dog(name, age) {
  Animal.call(this, name)
}

inheritPrototype(Dog, Animal)
var d = new Dog()
d.sayName()