js原型

基本概念:

  • prototype:显性原型,获取共享的属性和方法
  • __proto__( [[Prototype]] ):隐式原型,指向构造函数的原型,如:function a(){};    var b = new a();   b.__proto__ == a.prototype
  • constructor:指向的是构造函数,如:var a = new Array();   a.construtor === Array

prototype只有函数有

__proto__是对象就有,不过不推荐使用(比较耗性能),推荐使用Object.getPrototypeOf(obj)


Object.prototype.__proto__ = null,可以理解Object就是原型链最高级

Function.__proto__.__proto__ == Object.prototype,可以理解Function继承自Object


1、原型链方式 

function AA(name) { this.name = name }
AA.prototype.sex = 'man'

function BB() {  }

BB.prototype = new AA()

BB.prototype.cunstructor = BB

BB.prototype.sex === 'man'

缺点 

  1. 子类创建实例时无法给父类构造函数传参
  2. 父类中如果有引用类型的属性时,所有子类都可操作该属性,例子

2、构造函数方式 

function AA(name) { this.name = name }
AA.prototype.sex = 'man'

function BB(name) {
    AA.call(this, name)
}

BB.prototype.sex === undefined

缺点 

  1. 这种方式虽然能给父类构造函数传参,但是无法获取父类的原型属性

3、原型链加构造函数组合方式继承

function AA(name) { this.name = name }
AA.prototype.sex = "man"
function BB() { AA.call(this, "BB") } // 调用AA,实例化后也可以用name

// 方式一,推荐
// 继承,BB.prototype.__proto__ == AA.prototype
BB.prototype = Object.create(AA.prototype)

// 方式二
// 将父类的实例对象做原型,可以将AA的实例属性赋给BB并将__proto__指向AA的原型
// BB.prototype = new AA()

BB.prototype.cunstructor = BB  // 需要重新指定construct,否则指向AA

BB.prototype.sex == "man"

缺点 

  1. 这种方式解决了大部分缺点,但还是有引用类型属性共享的问题,不过只涉及原型上的引用类型属性(通过this操作也会有影响)

4、圣杯模式 

function AA (name) { this.name = name }
AA.prototype.sex = 'man'

function BB () {}

/** function _extends (b, a) {
    function _() {}
    _.prototype = a.prototype
    b.prototype = new _()
    b.prototype.constructor = b
} */

function _extends = (function () {
    function _() {}
    return function (b, a) {
        _.prototype = a.prototype
        b.prototype = new _()
        b.prototype.constructor = b
    }
})()

_extends(BB, AA)
  1.  这种方式和原型链方式的区别就是不会把父类的私有属性赋给子类的原型

5、setPrototypeOf 

function AA () {}
AA.prototype.age = 0

function BB () {}

// 将BB.prototype.__proto__指向AA.prototype
Object.setPrototypeOf(BB.prototype, AA.prorotype)

BB.prototype.constructor = BB

BB.prototype.age === 0

6、class/extends

继承的实现就是将父类原型添加到原型链上


多个继承:

若有多个继承可用Object.assign(target,...sources),会将所有sources的对象复制到target目标对象,注意:重复的属性会被覆盖

继承使用:Object.assign(BB.prototype, AA.prototype)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值