原型(对象属性)
在JavaScript中,每一个函数都有一个对象属性(prototype),其指向另一个对象。
为何要设计prototype对象属性?
JavaScript语言在设计时,其设计师不想将这门语言设计的过为简单,不想进步语言学习门槛,因而没有引入类。然而其借鉴了new关键字,通过new关键字加构造函数的形式创立实例对象。如果只有构造函数,那么怎么实现多个实例对象之间共享属性和办法呢?为了实现共享,设计师为构造函数增加了prototype属性,该属性指向一个对象,所有实例之间共享的属性和办法就放在这个对象上,不须要共享的属性和办法就放在构造函数外面,实例对象在创立实现之后,将主动引入prototype对象的属性和办法。
function Person(name) { this.name = name}// 原型上增加一个共享方法Person.prototype.say = function () { console.log(`my name is ${this.name}`)}let zs = new Person('zhangsan')// 实例对象能够拜访原型上的共享方法zs.say()
原型链
在原型中咱们得悉,所有的构造函数都有一个prototype属性,由此构造函数创立的实例对象都能主动获取prototype下面共享的属性和办法。那么实例对象是如何获取的?实例对象都有实例对象和原型之间的一种链接,也就叫原型链。
function Person(name) { this.name = name}Person.prototype.say = function () { console.log(`my name is ${this.name}`)}let zs = new Person('zhangsan')// 实例对象proto属性指向构造函数的原型console.log(zs.__proto__ === Person.prototype) // true
因为原型也是一个对象,能够看作是Object的一个实例,因而,其__proto__属性指向Object的原型。
console.log(Person.prototype.__proto__ === Object.prototype) // true
因为所有function都是由Fucntion生成的,也就是所有的函数能够看作是Function的实例对象,因而函数的__proto__指向Function的原型。
console.log(Person.__proto__ === Function.prototype) // true
constructor
在每个函数的原型prototype中都有constructor属性,它保留了对函数的援用。
console.log(Person.prototype.constructor === Person)// 因为constructor保留了一个援用,因而能够用其实例化一个对象let lisi = new Person.prototype.constructor('lisi')lisi.say()