原型链与继承方式

86 阅读1分钟

一. new Function

创建了一个对象;
该对象的原型,指向了这个Function(构造函数)的prototype;
该对象实现了这个构造函数的方法;
根据一些特定的情况返回对象:
    如果没有返回值,则返回创建的对象;
    如果有返回值,是一个对象,则返回该对象;
    如果有返回值,不是一个对象,则返回创建的对象;
    
function newObj (farther) {
    if (typOf farther !== 'function') {
        throw new Error ('xxxxxxxxx')
    }
    var obj = Object.create(farther.prototype)
    var result = farther.apply(obj, Array.prototype.slice.call(arguments, 1))
    return result && typeOf result === 'object' && result !== 'null'? result : obj;
}

二. 原型链

function Person (name, age) {
    this.name = name;
    this.age = age
}
var p = new Person;

p.__proto__ = Person.prototype
Person.prototype.constructor = Person
p本身是没有constructorde,所有p会在自己的__proto__上面去找,也就是 Person.prototype。它的上面是有constructorde的。也就是Person。所以 p.constructor 指向 Person;

三. 继承

原型链继承
function Person () {
    this.name = 'll'
}
Person.prototype.getName = function () {
    console.log('lll')
}
function Child () {}
Child.prototype = new Person()
Child.prototype.constructor = Child
隐含的问题:
1. 如果有属性是引用类型,一旦某个实例,修改了这个属性,所有的都会被改;
2. 创建Child的时候不能传参数

构造函数继承
想办法Person的属性添加到Child上面,而不是都存在原型对象上,防止被实例共享
function Person (actions, name) {
    this.name = 'll'
    this.actions = ['eat', 'work', 'sleep']
}
 function Child (paly) {
     Person.apply(this, Array.prototype.slice.call(arguments, 1))
     this.paly = paly
 }
 隐含的问题:
 1. 属性或者方法想被继承的话,只能在构造函数中定义;
 2. 如果方法在构造函数中定义了,那么每次创建实例都会创建一遍方法;
 
 组合继承
 function Person (actions, name) {
    this.name = 'll'
    this.actions = ['eat', 'work', 'sleep']
}
Person.prototype.work = function (){
    console.log('lll)
}
function Child (paly) {
     Person.apply(this, Array.prototype.slice.call(arguments, 1))
     this.paly = paly
}
Child.prototype = new Person()
Child.prototype.constructor = Child

ES6继承
class Person {
    
}
class Child extends Person {
    constructor(){
        super()
    }
}