原型
function Person(name, age){
this.name = name
this.age = age
}
Person.prototype.printName = function(){
console.log(this.name)
}
var p1 = new Person('hsc', 25)
p1.printName()
原型图
- 通过函数定义了类Person,类(函数)自动获得属性prototype(原型)
- 每个类的实例都会有一个内部属性__proto__,指向类的prototype属性
- 实例调用方法(p1.printName()),会先去自身找,找不到,会自动去__proto__中找,也就是原型上去找,原型相当于一个公共的容器,存放一些共用的代码等,可以减少内存的浪费
原型链
知道了原型,那么原型链又是什么呢?有什么用呢?先来看个例子
var mycars=new Array(1,2,3)
mycars.valueOf() //[1, 2, 3]
这个valueOf方法哪里来的?
首先实例本身没有这个方法,接着去原型mycars.__proto__找,也就是Array.prototype上找,发现也没有这个方法,但是mycars.__proto__里面也有个__proto__,发现valueOf方法在这个里面,如下图
寻找valueOf方法
- 首先原型Array.prototype也是一个对象,它也是由函数构造出来的。所以它的__proto__指向了构造它的函数的原型。
- mycars.__proto__.__proto__.constructor为Object可以知道,构造Array的原型mycars.__proto__(即Array.prototype)的函数就是Object。
其实任何类的prototype属性本质上都是个类Object的实例,所以prototype也和其它实例一样也有个proto内部属性,指向其类型Object的prototype - valueOf方法就在Object的原型上
总结一下: valueOf方法的寻找过程。
①首先在实例mycars本身去寻找
②没有的话,去构造这个实例的函数Array的原型prototype(即Array.prototype)上去寻找
③仍然没找到的话,去构造Array.prototype的函数Object的原型prototype (即Object.prototype)上去寻找
④就这样一级一级的往上找。最终在Array.prototype.__proto__上找到了,即在mycars.__proto__.__proto__
⑤总的来说就是 实例.__proto__.__proto__....... 这样的一条链上找下去,这条链就是原型链
可能说的有点抽象,结合下面的原型链的图来理解
补充
- instanceof的作用是判断一个对象是不是一个函数的实例(比如obj instanceof fn)。实际上就是判断这个函数的prototype是不是在这个对象的原型链上,即obj.__proto__ === fn.prototype;obj.__proto__.__proto__ === fn.prototype;obj.__proto__....__proto__ === fn.prototype,只要有一个成立即可
- 三句话可以解释一切关于原型方面的问题(参考自原型,原型链,Function,Object的理解,强烈推荐看看里面的题目):
①当new一个函数的时候会创建一个对象,【函数.prototype === 被创建对象.__proto__】
②函数也是一个对象,一切函数都是由Function这个函数创建的,所以【一切函数.__proto__ === Function.prototype】
③一切函数的原型对象都是由Object这个函数创建的,所以【一切函数.prototype.__proto__ === Object.prototype】(Object.prototype除外,☆☆☆☆☆Object.prototype.__proto__ === null☆☆☆☆☆)
最后附上一张自己的手绘图
image
网友评论