一般对象的属性规则
- 对象有
__proto__
属性,函数有prototype
属性; - 对象由函数生成
- 生成对象时,对象的
__proto__
属性指向函数的prototype
属性 - 对象一般分为两种,一种是普通的对象
{}
或者new Fn()
出来的对象,这种对象没有prototype
,另一种就是函数对象,这种对象有__proto__
和prototype
一般对象
创建空对象时,实际上我们是用Object函数来生成对象的,对象o的__proto__
属性就是Object.prototype
,并且o.prototype==undefined
,所以这种对象时没有prototype
的
{
let o={};
o.__proto__==Object.prototype;//true
o.prototype//undefined
}
我们也可以显式的使用Object函数来创建对象,对象o的__proto__
属性就是Object.prototype
,并且o.prototype==undefined
,所以这种对象时没有prototype
的
{
let o = Object()
o.__proto__ === Object.prototype//true
o.prototype//undefined
}
当我们使用函数来创建自定义的对象时,对象mo的__proto__
属性就是MyObj.prototype
,并且mo.prototype==undefined
,所以这种对象时没有prototype
的
function MyObj(){}
let mo = new MyObj();
mo.__proto__ === MyObj.prototype//true
mo.prototype//undefined
函数对象的__proto__
一般函数对象都是由
Function
函数生成的,所以他们的__proto__
属性,都会指向Function
的prototype
{
function fn(){};
fn.__proto__==Function.prototype//true
}
{
//Function函数本身
Function.__proto__==Function.prototype//true
}
{
//Object函数本身
Object.__proto__==Function.prototype//true
}
一般函数对象的prototype
一般函数默认的prototype
是一个类型为"object"
的对象,它有两个属性:constructor
和__proto__
。其中constructor
属性指向这个函数自身,__proto__
属性指向Object.prototype
,这说明一般函数的prototype
属性是由Object
函数生成的。
{
function fn(){};
console.log(fn.prototype)//object
//{constructor: ƒ}
//constructor: ƒ fn()
//__proto__: Object
fn.prototype.constructor==fn//true
fn.prototype.__proto__==Object.prototype;//true
}
特殊函数的prototype
如果Object.prototype.__proto__ === Object.prototype
。
那么,问题出现了,Object.prototype.__proto__
属性指向了它自身,这样以__proto__
属性构成的原型链就再也没有终点了!所以为了让原型链有终点,在原型链的最顶端,JavaScript
规定了Object.prototype.__proto__ === null
{
console.log(Object.prototype);
Object.prototype.constructor==Object//true
Object.prototype.__proto__==null;//true
}
按照我们最开始提出的通用规则,一个"function"
类型的对象,应该是由Function
函数生成的,那它的prototype
属性应该指向Function.prototype
,也就是Function.prototype.__proto__ === Function.prototype
。和Object
函数同样的问题出现了:循环引用。所以JavaScript
规定Function.prototype.__proto__ === Object.prototype
,这样既避免了出现循环引用,又让__proto__
构成的原型链指向了唯一的终点:Object.prototype.__proto__ === null
。
{
console.log(Function.prototype);
Function.prototype.constructor==Function//true
Function.prototype.__proto__==Object.prototype;//true
}
下面一张图描述了javaScript原型链之间的关系
网友评论