prototype、__ptoto__
2019-11-08 本文已影响0人
royluck
// 父类
let SuperClass = function (val) {
this.name = '父类'
this.supVal = val
}
SuperClass.prototype.getName = function () {
console.log(this.name)
}
let sup = new SuperClass('1111')
// 子类(继承父类SuperClass)
let SubClass = function (val) {
this.name = '子类'
this.subVal = val
}
SubClass.prototype = new SuperClass()
SubClass.prototype.getSubVal = function () {
console.log(this.subVal)
}
// 验证:
// SuperClass.prototype.constructor == SuperClass // =>true
// Object.prototype == SuperClass.prototype.__proto__ // => true
// Object.prototype == Function.prototype.__proto__ // => true
// SuperClass.prototype.__proto__ == Function.prototype.__proto__ // => true
// SuperClass.prototype == SubClass.prototype.__proto__ // => true
// SubClass.__proto__ == Function.prototype // => true
// SubClass.prototype.__proto__ == SuperClass.prototype // => true
// 实例出来的对象,其继承过来的supVal值为 undefined
// 这里不能给父类supVal定义值,所以ES5有几种设计模式,用于解决这种情况
// 例如:构造函数继承 组合继承 原型式继承 寄生式继承 寄生组合式继承...
// ES6新增了语法糖 class,因此不用像ES5那样创建类
let sub = new SubClass('0000')
> 下面以上述两个类为例,讨论 proto、 prototype、 constructor的关系:
关键概念前置:
- 每个对象都有构造函数constructor,它是从一个对象指向一个函数,含义就是指向该对象的构造函数(所以constructor指向一定是函数)
- 上述的sub对象,其constructor构造函数指向是SuperClass,因为其prototype继承了SuperClass
- 所以:sub.constructor == SuperClass.prototype.constructor // =>true
- 因此上述的sub对象属性constructor,实际是从其proto原型链上继承过来的,非其本身属性
- prototype属性只有函数才有,每个函数(任意创建一个函数)都会自动生成一个默认的属性prototype,生成prototype的同时,跟自动生成this一样,会自动生成constructor属性
- prototype的constructor默认指向这个函数
-上述 SuperClass.prototype.constructor == SuperClass // =>true - 而 SubClass.prototype.constructor == SubClass // =>false 因为为了继承SuperClass,SubClass.prototype被指向了SuperClass实例,所以其constructor指向是SuperClass
- (在《JavaScript设计模式》一书,有句话'constroutcto属性指向的就是拥有整个原型对象的函数或对象。'这里的'或对象'让我觉得很懵逼,还有网上有些对原型链的解释,良莠不齐,所以这也是我为什么自己要重新整理梳理它们关系的原因,如果理解有误,也望指出)
- proto 对象、函数均有,它们指向对应的原型链prototype
- proto 永远指向prototype,其到顶是null
- 所有构造器/函数的proto都指向Function.prototype(Function.prototype是一个空函数)
- 上述sub其proto指向SubClass.prototype;sup其proto指向SuperClass.prototype
- SubClass()其proto指向SuperClass.prototype
- SuperClass()其proto指向Function.prototype
- Object()其proto指向Function.prototype
- SuperClass.prototype其proto指向Object.prototype
- Function.prototype其proto指向Object.prototype
- Object.prototype其proto指向null
思考拓展: 在平时的代码中,有时候你能看到 SubClass.prototype = new SuperClass()
指向一个实例,有时 SubClass.prototype = Object.create(SuperClass.prototype)
指向原型,那么二者有什么区别呢?
更新:20200629
- 构造函数: JS中所有函数都可以作为构造函数,前提是被new操作符操作;
- 原型对象: 构造函数有一个prototype属性,这个属性会初始化一个原型对象;