在 JavaScript 中,函数也是属于对象,可以像其他对象一样访问属性,其中便有一个属性叫原型 prototype,值为一个对象,默认,原型有一个 constructor 属性,指向了构造函数本身。function Person () { return ‘hi’}Person.prototype // {constructor: ƒ}Person.prototype.constructor // ƒ Person() {}用图来表示:我们可以对这个属性进行操作,但这个属性,只有在对函数进行构造调用的时候才会起作用???? 为原型添加属性和方法function Person (name) { this.name = name}Person.prototype.smart = truePerson.prototype.run = function () { console.log(‘running’)}// 或者一次性添加Person.prototype = { smart: true, run() { console.log(‘running’) }}???? 使用// …let a = new Person(‘a’)a.name // aa.smart // truea.run() // running???? instanceof用来检测构造函数的原型是否存在于实例的原型链上// …let b = new Person(‘b’)b instanceof Person // trueb instanceof Object // true???? hasOwnPrototype该方法来判断是否自身属性,如:function Person () { this.name = ‘Jon’}Person.prototype.name = ‘people’Person.prototype.age = 18let jon = new Person()jon.hasOwnProperty(’name’) // truejon.hasOwnProperty(‘age’) // falseage 为原型上的属性,所以为 false???? isPrototypeOf该方法来判断对象是否是另一个对象的原型,如:let base = { name: ‘people’, age: 18}function Person () { this.name = ‘Jon’}Person.prototype = baselet jon = new Person()base.isPrototypeOf(jon) // true???? getPrototypeOf当不知道对象的原型具体是哪个的时候,可以使用该方法来判断,如:let base = { name: ‘people’, age: 18}function Person () { this.name = ‘Jon’}Person.prototype = baselet jon = new Person()Object.getPrototypeOf(jon) // { name: ‘people’, age: 18 }???? _ proto 引用《MDN _ proto _ 》 的解释:Object.prototype 的 _ proto _ 属性是一个访问器属性(一个 getter 函数和一个 setter 函数), 暴露了通过它访问的对象的内部原型 (一个对象或 null)。也就是说,每个对象都有一个该属性,便携访问原型对象,直指原型对象:let base = { name: ‘people’, age: 18}function Person () { this.name = ‘Jon’}Person.prototype = baselet jon = new Person()jon.proto // { name: ‘people’, age: 18 }用图来表示:与 prototype 不同的是, proto _ 是对象的属性,prototype 是构造函数的属性????【ES5】Object.create(..)该方法创建一个新对象,使用现有的对象来提供新创建的对象的 _ proto :let base = { name: ‘people’, age: 18}let jon = Object.create(base)jon.proto // { name: ‘people’, age: 18 }???? 原型链当访问对象的一个属性时,js 引擎会遍历自身对象的属性,如果找不到,便会去原型上查找该属性,如果还是找不到,便会继续查找原型的属性,直到到 Object 原型由于原型是一个对象,是对象便会有一个原型,有原型说明存在构造函数,如 Person 例子,查看原型的构造函数是啥:// …Person.prototype.proto.constructor // ƒ Object() { [native code] }Person.prototype.proto.constructor === Object // true说明 Object 是 Person 原型 的构造函数说明 Person 原型 的 _ proto _ 会指向 Object.prototype,因为 _ proto _ 能快捷访问原型:// …Object.getPrototypeOf(jon.proto) === Object.prototype // true// 或者jon.proto.proto === Object.prototype // true// 或者Person.prototype.proto === Object.prototype // true用图表示就是:举个例子:// …let a = new Person(‘a’)a.toString() // “[object Object]“Person 函数和原型上都没有 toString 方法,所以只能调用 Object 上的 toString 方法。注意:基于同一个构造函数生成的对象,共享函数的原型,如:// …let b = new Person(‘b’)b.name // bb.smart = falseb.smart // falsea.smart // falseb.proto === a.proto // true对 b 的 smart 属性进行修改,a 访问 smart 也有原先的 true 变为 false 了。???? Object.prototypeObject.prototype.proto // nullnull 是什么意思?此处无对象的意思,说明 Object.prototype 没有原型,查到这里就停止查找了,如果在找不到目标属性,就返回 undefined。???? 自身属性优先如果自身和原型上存在同名属性,会优先使用自身属性,例如:function Person () { this.name = ‘Jon’}Person.prototype.name = ‘people’let jon = new Person()jon.name // Jon???? 总结自:《JavaScript 深入之从原型到原型链》 by 冴羽《Object.create()》 by MDN《 proto _ 》 by MDN《JavaScript 面向对象编程指南(第 2 版)》第 5 章 原型《Node.js 开发指南》附录 A进击的小本本 更新时间为:周二,周四,周六,内容不定。如想查看最新未完成总结,可请查看:https://github.com/KaronAmI/blog如有启发,欢迎 star,如有错误,请务必指出,十分感谢。????