面向对象

一、类的声明

//构造函数

function Parent() {

    this.firstName = 'Hou';

}

Parent.prototype.say(){

    console.log('hello');

}

//ES6

class Parent2(){

    consutractor () {

        this.name = 'Zhang';

    }

}

二、类的实例化

var parent= new Parent ();

三、类的继承

1. 借助构造函数实现继承

    原理:改变函数运行时的上下文,即this的指向

function Child1() {

    Parent.call(this);

    this.lastName = 'Peng';

}

    缺点:父类原型对象上的方法无法被继承

console.log(new Child1().say());    //出错,找不到此方法

2. 借助原型链实现继承

    原理:改变子类的prototype(即其实例的__proto__)属性指向其父类的实例

function Child2() {

    this.lastName = 'Peng';

}

Child2.prototype = new Parent();

    原型链原理:实例的__proto__属性指向其构造函数的prototype属性

new Child2().__proto__ === Child2.prototype    //true

    缺点:原型链中的原型对象是共用的,子类实例的原型对象是同一个引用,当一个实例的属性改变时,其他实例也跟着改变

var c21 = new Child2();

var c22 = new Child2();

c21.__proto__ === c22.__proto__    //true

3. 组合方式实现继承

    原理:结合构造函数和原型链方法的优点,弥补了此两种方法的不足    

function Child3() {

    Parent.call(this);

    this.lastName = 'Peng';

}

Child3.prototype = new Parent();

    缺点:父类构造函数执行了两次

4. 组合方式实现继承的优化1

    原理:子类的原型对象引用父类的原型对象

function Child4() {

    Parent.call(this);

    this.lastName = 'Peng';

}

Child4.prototype= Parent.prototype;

    缺点:无法区分实例是子类还是父类的实例,实例的constructor属性为父类构造函数(方法2,3也有同样的缺陷)

var c4 = new Child4();

console.log(c4 instanceof Child4);    //true

console.log(c4 instanceof Parent);    //true

console.log(c4.constructor);    //Parent;

5. 组合方式实现继承的优化2,完美写法

    原理:利用Object.create()函数创建的对象

function Child5() {

    Parent.call(this);

    this.lastName = 'Peng';

}

Child5.prototype = Object.create(Parent.prototype);

Child5.prototype.constructor = Child5;

你可能感兴趣的:(面向对象)