原型&原型对象
先来一段简单的代码:
function Fun(name) {
this.name = name
}
var obj = new Fun('obj')
JavaScript中的对象都有一个[[Prototype]]内置属性(即部分浏览器实现的__proto__属性),这是一个访问器属性,通过这个可以访问对象的[[Prototype]];对象就是以这个属性为模板,来“继承”方法和属性。
JavaScript中的方法都有一个prototype属性,有一个constructor属性,指向其自身,即Fun.prototype.constructor === Fun。
每个对象的[[Prototype]] 属性都指向创建这个对象的函数的prototype,即Object.getPrototypeOf(obj)=== Fun.prototype
要注意,JavaScript中并没有“类”的概念,创建对象是通过从另外一个对象“复制”而来的,所有对象(不包括通过Object.create(null)创建的对象)都可以看做是从Object.prototype这个对象复制过来的。
严格意义上,JavaScript并没有“构造函数”一说,只有“函数构造器”或者“被构造调用的函数”。JavaScript任何一个函数,都可以通过new关键字调用成为“函数构造器”或者“被构造调用的函数”。
函数本身也是对象,那么函数的__proto__是什么呢?由上文可知,对象的__proto__属性指向创建它的函数的prototype,那么函数这个对象是由谁创建的呢?由new Function()创建的,因此,Fun.__proto__ === Function.prototype
同理,Object.getPrototypeOf(Function) === Function.prototype,因为Function本身就是一个函数,也是由自己创建的。
Object.getPrototypeOf(Object)=== Function.prototype,因为Object也是个函数,由Function创建。
原型链
每个对象都有__proto__属性,指向其原型对象,同时,原型对象也会有自己的__proto__属性,指向上一层的原型对象,如此一层一层的链式结构,最终指向了null,就形成了原型链。
那么,原型链有何作用呢?
前面说过,对象会从它的__proto__中继承属性,这种链式的结构,就实现了“继承”的效果。当访问一个对象的某个属性时,会先在对象自身属性里寻找,如果找不到,则会沿着原型链,一级一级的向上寻找该属性,如果一直找到Object.prototype也没有找到,则认为没有该属性,返回undefined。
也就是说,对象会将它的属性“委托”给其原型所指向的对象,如果没有该属性,则在原型指向的对象上寻找该属性。
tips:如何判断属性是对象自身的还是原型链上的?
用hasOwnProperty()方法即可判断。
原文地址:https://www.cnblogs.com/melonsinsummer/p/prototype.html