代码改变世界

对于JavaScript对象的prototype和__proto__的理解

2016-06-01 22:07  盛世游侠  阅读(1152)  评论(0编辑  收藏  举报

一、Object和Function的关系:

刚学JavaScript的时候,看书上说JavaScript中万物皆对象,而javascript中的其他对象都是从Object继承而来,包括内置对象。瞬间觉得Object碉堡了!

后来,又认识了Function,才知道原来Function才是隐藏在幕后的大BOSS,Object只不过是个大师兄。

Object和Function都是JS自带的函数对象,Function比较牛逼点,因为它是Object的构造函数,而且Object的__proto__属性指向它的prototype,这意味着Object的那点玩意儿还是从它这里继承的。

Object.constructor === Function; //true
Object.__proto__ === Function.prototype; //true

Function.prototype.duang = function(str){console.log(str+"真duang啊!")};

Object.duang("你的头发");
//你的头发真duang啊!

Object instanceof Function //true

 

然而后来我又发现“javascript中的其他对象都是从Object继承而来”这句话其实是错的,准确的说法应该是:“javascript中的其他对象都继承了Object.prototype中的属性和方法

Function.prototype.duang = function(str){console.log(str+"真duang啊!")};
Object.duang(
"你的头发"); var of = {}; of.duang("猫咪");
// 你的头发真duang啊! //Uncaught TypeError: of.duang is not a function(…)(anonymous function)


Function.prototype.duang = function(str){console.log(str+"真duang啊!")};
Object.prototype.duang =
Function.prototype.duang;

var of = {};

of.duang(
"猫咪"); //猫咪真duang啊!

 

 

二、普通对象和函数对象:

JavaScript中万物皆对象,但对象之间也是有区别的。分为函数对象和普通对象。

函数对象可以创建普通对象,普通对象没法创建函数对象,普通对象JS世界中最低级的小喽啰,啥特权也没有。

凡是通过new Function创建的对象都是函数对象,其他都是普通对象(通常通过Object创建),可以通过typeof来判断。 

function f1(){};
typeof f1 //"function"


var o1 = new f1();
typeof o1 //"object"

var o2 = {};
typeof o2 //"object"


定义一个函数或函数表达式时,是使用Function方法去创建的,所以创建出来的都是函数对象;
var f1 = function(){} 或 function f1(){}的创建过程都是:

var f1 = new Function(); 

 

三、原型与各方面的关系:

原型就是其构造函数的一个普通实例对象。

对于任何一个普通的函数f1:function f1(){};

f1.prototype 就是f1的一个实例对象,因为它不是一个函数声明或函数表达式,所以它是通过new它的构造函数创建的,
是通过Object创建的,所以它是普通对象。

一个函数的prototype的创建过程如下:

var temp1 = new f1();
f1.prototype = temp1;

 

但Function的原型不一样,它是一个函数对象,因为它的构造函数是Function,它通过Function创建,所以它是函数对象!
它的创建过程如下:

var temp = new Function();
Function.prototype = temp;

 

f1.prototype其他关系如下:

f1.prototype.constractor === f1;

f1.prototype.__proto__ === Object.prototype;

f1.prototype.__proto__.constractor === Object;

f1.prototype.constractor.prototype = f1.prototype;

f1.prototype.__proto__.constructor.prototype === f1.prototype.__proto__ === Object.prototype

 这里需要特别注意的是:

1、Object.prototype.__proto__ === null;

 

2、Object.__proto__ === Function.prototype
Object是函数对象,是通过new Function()创建,所以Object.__proto__指向 
Function.prototype。

 

3、Function.__proto__ === Function.prototype
Function 也是对象函数,也是通过new Function()创建,所以 
Function.__proto__指向Function.prototype。

自己是由自己创建的,好像不符合逻辑,但仔细想想,现实世界也有些类似,你是 
怎么来的,你妈生的,你妈怎么来的,你姥姥生的,……类人猿进化来的,那类人 
猿从哪来,一直追溯下去……,就是无,(NULL生万物)
正如《道德经》里所说“无,名天地之始”。

 

4、Function.prototype.__proto__ === Object.prototype

其实这一点我也有点困惑,不过也可以试着解释一下。
Function.prototype是个函数对象,理论上他的__proto__应该指向 
Function.prototype,就是他自己,自己指向自己,没有意义。
JS一直强调万物皆对象,函数对象也是对象,给他认个祖宗,指向 
Object.prototype。Object.prototype.__proto__ === null,保证原型链能够正 
常结束。