Javascript中的原型
2016-03-09
原型
首先可以通过__proto__
属性来查看对象的原型是什么,
那么这个对象的原型怎么来的,通过构造函数上的prototype
属性来定义,
普通对象是没有prototype
属性的
需要特别分清楚的是:一个对象的原型不等于自己的prototype属性,而是等于它的构造函数的prototype属性,很长时间,我对这个概念的理解是混乱的,上代码说明
首先要确定哪些东西是语言定义的,(或者说是说死的,不要问为什么)
prototype
而哪些东西是根据语法规则产生的
Function类型对象:
有prototype属性,他的prototype属性默认是
1 | constructor: 他自己 |
比如:
1 | function A() {} |
Object对象本身是个Function类型对象,他是有prototype属性的,而prototype属性上挂的属性和方法就会???
1 | a.__proto__ === obj.constructor.prototype === A.prototype |
Object类型对象 全都是通过构造函数生成的,他是有原型的,但是没有prototype属性
function A() {}
var a = new A();
由于JavaScript的所有对象都是通过构造函数生成的,而所有构造函数都有prototype属性(其实是所有函数都有prototype属性),所以所有对象都有自己的prototype原型对象。
因此,一个对象的属性和方法,有可能是定义它自身上面,也有可能定义在它的原型对象上面。由于原型本身也是对象,又有自己的原型,所以形成了一条原型链(prototype chain)。
比如,a对象是b对象的原型,b对象是c对象的原型,以此类推。
因为追根溯源,
最源头的对象都是从Object构造函数生成(使用new Object()命令),
所以如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype。
那么,Object.prototype有没有原型呢?
回答可以是有,也可以是没有,
因为Object.prototype的原型是没有任何属性和方法的null。
Object.prototype对象的原型是null,由于null没有任何属性,所以原型链到此为止。
1 | Object.getPrototypeOf (); |
最简单的情况:一个对象的原型是在其构造函数的prototype属性上
妈蛋!!!
好乱啊
从源头开始
说明:根据js的语言标准,浏览器中__proto__
代表着这个对象的原型,不要问什么
Object对象
Object对象是一个Function类型对象,也是个构造函数
- 他的原型是:
Object.__proto__: function() {}
所有函数类型的对象的__proto__
都是这个 - 他的prototype属性是:
Object.prototype
,这是语法定义的,不需要问为什么
[Object.prototype]是个Object类型的对象, 他应该是语言层面的定义,他有什么属性和方法都是说定了的
所以你不能因为他的constructor是Object,然后就说她的构造函数是Object,
所以
1 | Object.prototype.__proto__ === Object.prototype // 这是不对的 |
先要满足语言上的定义,在来说语法规则
所以,Object.prototype对象的原型是null,为什么,没有为什么,就是这样
规则是什么
一个对象的原型是其构造函数的prototype属性
前面说的都是不讲理的话,现在可以好好讲下道理,道理就是上面这句话
1 | function A() {} |
那么A.prototype是什么,
- 首先,是个Object类型的对象
- 他有一个constructor的属性,constructor是A自己
- 还有一个原型(
__proto__
),是Object.prototype
这里又不能讲道理了,语言就是这么定的,这个东西和实例对象息息相关
其实A本身也有原型,即A.__proto__ : function() {}
,这里是可以讲道理的
1 | console.log(A.constructor.prototype); // function() {} |
这些实例对象是没什么关系的,任何函数默认都是如此
回到A.prototype,上面说的是默认情况,但是这个对象可以改的
比如为了实现继承:
1 | function Pa() {} |
那么A.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype
是什么?
因为 A.prototype.constructor === A
, 所以上面无论写多少都是A.prototype