实例

var animal = function() {};var dog = function() {};animal.prototype.price = 20;animal.price = 1000;dog.prototype = animal;var cat = new animal();var tidy = new dog();// 上面两行别离输入什么?console.log(cat.price);console.log(tidy.price);

要了解原型和原型链首先要晓得几个概念:

  • 在js里,继承机制是原型继承。继承的终点是 对象的原型(Object prototype)。
  • 所有皆为对象,只有是对象,就会有 proto 属性,该属性存储了指向其结构的指针。
  • Object prototype也是对象,其 proto 指向null。
  • 对象分为两种:函数对象和一般对象,只有函数对象领有『原型』对象(prototype)。
  • prototype的实质是一般对象。
  • Function prototype比拟非凡,是没有prototype的函数对象。
  • new操作失去的对象是一般对象。
  • 当调取一个对象的属性时,会先在自身查找,若无,就依据 proto 找到结构原型,若无,持续往上找。最初会达到顶层Object prototype,它的 proto 指向null,均无后果则返回undefined,完结。
  • 由 proto 串起的门路就是『原型链』。
    看图

cat调用price

  • 查看自身,没有price,依据 proto 找到 animal prototype对象。
  • 在animal prototype对象中找到了price,所以 cat.price 后果为20。
  • 如果无 animal.prototype=20,则会依据animal prototype对象的 proto 找到Object prototype,Object prototype中的 proto 指向null,若仍没有找到price,后果则为undefined。

tidy调用price

  • 查看自身,没有price,依据 proto 找到dog prototype。
  • dog prototype = animal,这里能够这样了解: prototype实质也是一个对象,因而能够从新赋一个对象,无论是函数对象还是一般对象。事实上,每个 prototype 会有一个预约义的constructor属性用来援用它的函数对象。
  • 在animal中找到了price, 所以 tidy.price 后果为1000。
  • 如果无 animal.price = 1000,则会依据animal的 proto 找到下一个对象,最终都没有找到 price,后果就为undefined。

进阶学习:

创立一个对象的形式{}、new Object()构造函数Object.create()此办法将新对象的proto更改并指向create的入参对象。instance of VS constructorinstance of 原理:查看右边对象与左边对象是否在同一条原型链上。constructor原理:取对象的proto属性指向的prototype对象上的constructor字段。
cat instanceof animal === truecat.__proto__ === animal.prototypeanimal.prototype instanceof Object === trueanimal.prototype.__proto__ === Object.prototypecat instanceof Object === true// but,cat.constructor === animal // truecat.constructor === Object // false

new运算符的原理

  • 创立一个空对象,它的proto等于构造函数的原型对象(能够用Object.create()实现)
  • 构造函数以第1步创立的对象做为上下文,是否会返回一个对象
  • 若第2步返回了对象,则应用该对象作为新实例,否则用第1步创立的对象作为新实例
var myNew = function (func) {var o = Object.create(func.prototype)var i = func.call(o)return typeof i === 'object' ? i : o}

继承
类的申明:

function
class
生成实例:new

继承的几种形式:

  • 借助构造函数,父类的作用域指向子类
  • Parent.call(this) // this是Child类的上下文
  • 毛病:不能继承原型链属性
  • 借助原型链

  • Child.prototype = new Parent()
  • 毛病:子类所有实例共享原型对象;子类实例的constructor为Parent

    组合形式

  • Parent.call(this) // this是Child类的上下文
  • Child.prototype = Object.create(Parent.prototype)
  • Child.prototype.constructor = Child