原型(对象属性)

在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()

carry
58 声望7 粉丝

学无止境