原型是js中非常重要的东西,其串起了很多常用的js实现
最开始js没有原型这个概念。
为什么会出现原型呢?
假如我们有一个对象:
const obj = {}
然后我们添加一个属性,一个方法
obj.name = 'Tony Dog'
obj.sayName = function () {
console.log(this.name)
}
然后我们运行一下这个函数
obj.sayName() // Tony Dog
那假如我有十个类似于obj的对象呢,我想给他们都执行一下sayName
方法,就只能单独给每一个对象都挂载这样一个方法吗?
如果有一个东西,可以让这些对象共享同一个方法就好了。
我们有一个构造函数Creator
function Creator (name) {
this.name = name
}
const obj1 = new Creator('Joker')
const obj2 = new Creator('Kar')
现在我们想让这两个对象有同样的方法,然后分别打印出他们各自的名字
function Creator (name) {
this.name = name
}
Creator.prototype.sayName = function () {
console.log(this.name)
}
const obj1 = new Creator('Joker')
const obj2 = new Creator('Kar')
obj1.sayName() // Joker
obj2.sayName() // Kar
两个对象都是Creator
的实例,他们的构造函数的原型上的方法是共有的。
prototype
的出现,使得继承变得简单,ES5中的寄生组合继承与原型密不可分,当然现在ES6的类更加语义化了。
prototype
:只有构造函数才拥有的一个对象,我们在上面挂载属性和方法,这个构造函数创建的实例就都可以访问
构造函数创建的实例不具有prototype
属性,但是,实例有隐式原型__proto__
。
__proto__
:当实例需要访问一个方法的时候,会先在自己身上寻找,如果找不到,会到该实例的__proto__
属性上寻找,如果还找不到,再找一层__proto__
,直至Object
的原型null
。
也即:obj1.__proto__ === Creator.prototype; // true
并且:Creator.prototype.__proto__ === Object.prototype; // true
;
Object.prototype.__proto__ === null; // true