js 是唯一一个被广泛使用的基于原型继承的语言,所以在js中,原型与原型链至关重要
1. 普通对象与函数对象
万物皆对象,js将对象分为两种:普通对象和函数对象。其中,自带的函数对象包括:Function 和 Object;
示例永远是对知识点最好的说明,举例如下:
通过new functiong() 是区分函数对象和普通对象的关键, 所以上面变量的类型分别为:
console.log(typeof(f1), typeof(f2), typeof(f3));
//function function function
console.log(typeof(o1), typeof(o1), typeof(o1));
//object object object
Function Object 也都是通过 New Function()创建的,所以,
typeof(Object), typeof(function()) 也是funtion。
2.原型对象
js中,任何对象都隐含一个__proto__的属性, 即原型(属性),它就是一个Object类型对象,用于指向创建它的构造函数的原型对象。
任何情况下,只要创建了函数对象,就会根据特定规则创建一个prototype属性,指向函数的原型对象,注意prototype属性只有函数对象有,而普通对象没有
示例:
上面的例子中,Person.prototype就是原型对象,例中给原型对象添加了三个属性,分别是name, age, introduce另外,该原型对象还有一个默认的constructor属性。
注:js中所有原型对象都有一个默认属性,即constructor,并且指向protype所在函数
所以Person.prototype.constructor = Person
person1.__proto == person2.__proto == Person.prototype // persion1和persion2是通过 new persion创建,所以peision1和persion2的__proto__指向Persion的prototype
三.原型链
如上节所述,任何对象都隐含一个__proto__的属性,所以js在创建对象时,会存在一个proto的内置属性,用于指向创建它的函数对象的原型对象prototype,利用上面例子进行说明:
person1.__proto == Person.prototype
同时,Person.prototype也存在__proto
, 即Person.prototype.__proto == Object.prototype,
而且,Object.prototype对象同样存在__proto
属性,它的值是null,即Object.prototype.__proto__ == null
我们将由persion1,以及父的__proto串起来的直到Object.prototype.__proto为null的链叫做原型链,
即原型链的定义为: 每个对象和原型都有原型,对象的原型指向原型对象,而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。
四. Function 和 Object
在js中,一切对象都是Object的实例,一切函数都是Function的实例。
Object是构造函数,所以它是Function的实例,而Function.prototype是对象,所以Function.prototype是Object的实例对象。即:
五. 总结
1. 任何对象都有__proto__属性,该属性指向构造函数的prototype。
2. 函数对象除了有__proto__属性,同事拥有prototype属性,并指向该方法的原型对象。
3. 原型链的最终指向是null。
4. 原型链的形成是真正是靠__proto__ 而非prototype。