• JS系列


    创建对象的方式:

    • 字面量: var a = {};
    • new: function F() {}; var a = new F();
    • Object方法:var a = Object.create({a: 1}); 意思是a的原型是{a: 1}

    对象的属性说明(对象没有prototyte属性):

    例子: function F() {}; var a = new F();

    • a.constructor = F:对象、构造函数实例,都有constructor 属性,默认指向:它构造函数.prototyte.constrctor ; 构造函数的 prototype 对象 constrctor 属性指向本身;
    • a.__proto__ = F.prototyte: 对象有一个隐藏的__proto__属性(原型链),指向它的构造函数的prototype属性 
    • F.prototyte.constrctor = F; 构造函数的 prototype 的 constrctor 指向本身

    函数对象:

    • 有原型对象prototype(普通对象没有prototype) 函数实例的__proto__属性指向构造函数的prototype;
    • 构造函数的 prototype 属性的 constructor  属性指向本身;
    • 有__proto__ 隐藏属性,  Array.__proto__ 指向 Function.prototype (Function.prototype 比较特殊,是函数)

    new一个函数做了什么:

    例子: function F ( name ) { this.name = name ; } new F();

    1:创建一个新的空对象a

    2:将函数的this指向a对象

    3:将a对象的__proto__成员指向了构造函数F的prototype对象

    3:运行该F函数

    4:如果F函数没有返回值,或者返回的不是对象, 那么就返回a对象

    JS继承的方式 

    1. 原型链继承

    原理:

    1.子类的原型指向父类的实例;

    2.将子类原型上的constructor属性指向本身;

    3.错误的做法:Child.prototype = Parent.prototype;这样只能继承Parent.prototype上的属性,Parent方法本身的属性无法继承;

    缺点:

    1.无法多继承;

    2.原型对象所有属性都是共享,不小心修改后会影响所有子类;

    3.创建子类,无法向父类构造器传参

    父类: 

    function Parent () {this.name = 'Parent';  this.sex = 'boy';}; 

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

    子类:

    function Child () {  this.name = 'child'  }

    继承:

    Child.prototype = new Parent();

    Cat.prototype.constructor = Cat;(不加这一行:Cat.prototype.constructor 是 Animal,导致所有子类的constructor都指向Animal

    var c = new Child();

    child1.getName() // child 

    解析:

    c1通过构造函数Child生成的对象,就有属性name,并且属性值也是自己的child

    Child的原型被指向了父类构造函数Parent创建出来实例,就可以使用实例的所有方法以及属性,child1.getName()就生效;

    2. 构造函数继承(call或者apply)

    原理:

    在子类构造函数内部使用call或apply来调用父类构造函数;

    例子:

    function Parent (name) { this.name = name }
    function Child () {
    this.sex = 'boy'
    Parent.call(this, ...arguments)
    }

    优缺点:

    1. 可以解决原型链继承的3个缺点(无法多继承,无法向父类构造函数传参,子类共享原型对象属性)

    2. 但是无法继承父类原型上的方法及属性(原型链继承可以)

    3.组合继承

    概念:组合继承就是将原型链继承与构造函数继承组合在一起,从而发挥两者之长的一种继承模式 

    实现:

    1. 通过call/apply在子类构造函数内部调用父类构造函数

    2. 将子类构造函数的原型对象指向父类构造函数创建的一个匿名实例

    3. 修正子类构造函数原型对象的constructor属性,将它指向子类构造函数

    例子:

    function Parent (name) {

    this.name = name 

    }

    function Child (name, sex) {

    this.sex = 'boy'

    Parent.apply(this, [name])

    }

    Child.prototype = new Parent()

    Child.prototype.constructor = Child

    优点:

    • 可以继承父类实例属性和方法、父类原型属性和方法

    • 解决原型链继承中引用属性的共享的问题(父级的原型链Parent.prototype上的属性还是共享

    • 可向父类构造器传参

    缺点:

    • 父类构造函数会被调用两次
    • 生成了两个实例,浪费内存

    4. 寄生组合继承 - 最屌的继承方式

    与组合继承区别就在于:

    组合:Child.prototype = new Parent();Child.prototype.constructor = Child

    寄生:Child.prototype = Object.create(Parent.prototype)

     

     

    解释Object.create:

    使用了Object.create(Parent.prototype)创建了一个空的对象,并且这个对象的__proto__属性是指向Parent.prototype

    Object.create(null)创建的对象,它的__proto__属性设置为null,相当于是没有原型链了,连Object.prototype上的方法它都不能用了(toString、hasProperty)

    自己实现Object.create:

    function create(proto) {

    function F(){}

    F.prototype = proto;

    F.prototype.constructor = F;

    return new F();

    }

    优点:

    只调用了一次父类构造函数

     

    5. es6 class 继承

    class 中继承主要是依靠两个东西:
    • extends
    • super
    效果和之前我们介绍过的寄生组合继承方式一样(就是那个最屌的继承方式)

    6. 多继承

    原理:

    • 使用Object.create继承多个父类原型属性
    • 构造函数内部使用apply调用多个父类的实例方法

    例子:

    function Parent() { }

    function OtherParent() { }

    function Child(...arg) {

    Parent.apply(this, arg)

    OtherParent.apply(this, arg)

    }

    Child.prototype = Object.create(Parent.prototype)

    Object.assign(Child.prototype, OtherParent.prototype)

    Child.prototype.constructor = Child

     

    参考:https://juejin.im/post/5e75e22951882549027687f9#heading-36

  • 相关阅读:
    PHP Context学习系列《十》
    学习php记录《九》
    学习php记录《八》
    php学习记录《七》
    换到新工作后
    学习php记录《六》
    学习php记录《五》
    学习php记录《四》
    学习php记录《三》
    html基础
  • 原文地址:https://www.cnblogs.com/vs1435/p/6829505.html
Copyright © 2020-2023  润新知