天天看点

Js中Prototype、__proto__、Constructor、Object、Function关系介绍总结

1 js的对象都拥有内部属性 [[prototype]] 指向其原型对象。[[prototype]] 被称为原型属性。

2 内部属性不可以直接访问.error: obj[[prototype]],但是可以间接访问 [[prototype]]

a ecma:标准对象原型访问器object.getprototype(object)(到目前为止只有firefox和chrome实现了此访问器);

b 非标准访问器:__proto__(除了ie)

c obj.constructor.prototype

js的一切皆是对象,所以 函数也是对象.又因为对象拥有内部属性 [[prototype]],所以

函数也拥有内部属性 [[prototype]].

其次:函数同时拥有属性 prototype.prototype属性和 [[prototype]]并非同一个属性。

prototype属性指向一个对象,称为原型对象。所以:一个函数的原型属性(function’s prototype property ) 和函数实际的原型(prototype)没有关系

原型对象的作用:当函数fn被用作构造函数时,其所创建的所有实例的内部属性 [[prototype]] 指向 fn 的 prototype属性。

原型的作用:

1 构建原型链

当对象调用某个方法时,如果其本身不存在此方法,就会往其原型中寻找,直到原型链的顶端

原型链的作用:多个实例都需要的方法可以被抽出放到原型中,从而只需要定义一次,实现多个对象共享方法

js的所有对象都拥有constructor属性,指向其构造函数。函数的原型对象也是对象,所以原型对象也拥有constructor属性。并且js定下了规则:

即: 函数的prototype属性的constructor字段,指向当前prototype属性的拥有者,也就是构造函数本身

由 fn.prototype.constructor == fn;推导出来的结论:构造函数的实例的 constructor属性 指向其构造函数

推导:

首先在a本身寻找:没有找到 constructor属性.再往原型链向上查找,找到a的原型,也就是 fn.prototype,发现了 constructor属性。所以就相当于 构造函数的实例的 constructor属性始终指向其构造函数

function、object:js自带的函数对象

prototype,每一个函数对象都有一个显示的prototype属性,它代表了对象的原型(function.prototype函数对象是个例外,没有prototype属性)

__proto__:每个对象都有一个名为__proto__的内部隐藏属性,指向于它所对应的原型对象(chrome、firefox中名称为__proto__,并且可以被访问到)。原型链正是基于__proto__才得以形成(note:不是基于函数对象的属性prototype)。

关于上面提到的函数对象,我们来看以下例子,来说明:

通常我们认为o1、o2是对象,即普通对象;f1、f2、f3为函数。但是其实函数也是对象,是由function构造的,f3这种写法就跟对象的创建写法一样。f1、f2最终也都像f3一样是有function这个函数构造出来的

f1、f2、f3为函数对象,function跟object本身也是函数对象

js中每个对象(null除外)都和另一个对象相关联,通过以下例子跟内存效果图来分析function、object、prototype、__proto__对象间的关系

通过上面代码可以得出:

所有对象包括函数对象的原型链最终都指向了object.prototype,而<code>object.prototype.__proto__===null</code>,原型链至此结束。

animal.prototype是一个普通对象。

object是一个函数对象,也是function构造的,object.prototype是一个普通对象。

object.prototype.__type__指向null。

function.prototype是一个函数对象,前面说函数对象都有一个显示的prototype属性,但是function.prototype却没有prototype属性,即function.prototype.prototype===undefined,所有function.prototype函数对象是一个特例,没有prototype属性

object虽是function构造的一个函数对象,但是object.prototype没有指向function.prototype,即object.prototype!==function.prototype

在 javascript 中,每个函数对象都有名为“prototype”的属性(上面提到过function.prototype函数对象是个例外,没有prototype属性),用于引用原型对象。此原型对象又有名为“constructor”的属性,它反过来引用函数本身。这是一种循环引用(i.e. animal.prototype.constructor===animal)

constructor 属性是专门为 function 而设计的,它存在于每一个 function 的prototype 属性中。这个 constructor 保存了指向 function 的一个引用

注意:object.constructor===function;本身object就是function函数构造出来的

如何查找一个对象的constructor,就是在该对象的原型链上寻找碰到的第一个constructor属性所指向的对象

为什么 xx.constructor.prototype 可以访问到当前对象的原型。

'str'.constructor.prototype

'str'.constructor 指向当前对象的构造函数

(构造函数).prototype:即函数的prototype 属性

1) 函数有prototype属性,所以可以访问到

2) 函数的prototype属性会在创建实例的时候作为实例的原型而存在。

所以 'str'.constructor.prototype 就可以访问到当前对象实例的原型。

'str'.constructor == string

true.constructor == boolean

(1).constructor == number

{}.constructor == object

[].constructor == array

function(){}.constructor == function

result:全部都是:function function(){}

推论:内置对象的构造器,全部都是 <code>function function(){}</code>,包括function本身。所以js所有的内置对象的构造器都是 <code>function function(){}</code>

2.

number.__proto__ === function.prototype // true

boolean.__proto__ === function.prototype // true

string.__proto__ === function.prototype // true

object.__proto__ === function.prototype // true

function.__proto__ === function.prototype // true

array.__proto__ === function.prototype // true

regexp.__proto__ === function.prototype // true

error.__proto__ === function.prototype // true

date.__proto__ === function.prototype // true

function.prototype.__proto__ == object.prototype

object.prototype.__proto__ == object.prototype

number.prototype.__proto__ == object.prototype

boolean.prototype.__proto__ == object.prototype

string.prototype.__proto__ == object.prototype

array.prototype.__proto__ == object.prototype

regexp.prototype.__proto__ == object.prototype

error.prototype.__proto__ == object.prototype

date.prototype.__proto__ == object.prototype

推论:只有函数才有 prototype属性,所以上面的 xxx.prototype 中的xxx都是构造函数,又有2中的 xxx.__proto__。所以:xxx既可以是内置对象,也可以是构造函数。根据情景判断。object的所有实例的原型都是 object.prototype

object.constructor == function

function.prototype.__proto__ == object.prototype;

并且:object.prototype.__proto__ == null;

继续阅读