原型(prototype)
在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype
属性,这个属性指向函数的原型对象。
每个对象都有__proto__
属性,但只有函数对象才有 prototype
属性。
原型的作用
通过构造函数为实例对象定义属性有一个缺点,同一个构造函数的多个实例之间,无法共享属性,从而造成对系统资源的浪费。
JavaScript 继承机制的设计思想就是,原型对象的所有属性和方法,都能被实例对象共享。也就是说,如果属性和方法定义在原型上,那么所有实例对象就能共享,不仅节省了内存,还体现了实例对象之间的联系。
__proto__
JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__
的内置属性,用于指向创建它的构造函数的原型对象。
Number、String、Boolean类型有各自的共有属性__proto__
,各自的共有属性__proto__
又指向了普通对象Object的__proto__
,普通对象Object的__proto__
指向null
var o1 = {}
o1.__proto__ === Object.prototype //true
var n1 = new Number(1)
n1.__proto__ === Number.prototype //true
n1.__proto__.__proto__ === Object.prototype //true
n1.__proto__.__proto__.__proto__ === null //true
原型链
原型链的基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法。
JavaScript引擎在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefined。