搜索
简帛阁>技术文章>深入理解javascript原型和闭包(4)——隐式原型

深入理解javascript原型和闭包(4)——隐式原型

注意:本文不是javascript基础教程,如果你没有接触过原型的基本知识,应该先去了解一下,推荐看《javascript高级程序设计(第三版)》第6章:面向对象的程序设计。

上节已经提到,每个函数function都有一个prototype,即原型。这里再加一句话——每个对象都有一个__proto__,可成为隐式原型。

这个__proto__是一个隐藏的属性,javascript不希望开发者用到这个属性值,有的低版本浏览器甚至不支持这个属性值。所以你在Visual Studio 2012这样很高级很智能的编辑器中,都不会有__proto__的智能提示,但是你不用管它,直接写出来就是了。

 

 

上面截图看来,obj.__proto__和Object.prototype的属性一样!这么巧!

答案就是一样。

obj这个对象本质上是被Object函数创建的,因此obj.__proto__=== Object.prototype。我们可以用一个图来表示。

 

即,每个对象都有一个__proto__属性,指向创建该对象的函数的prototype

 

那么上图中的“Object prototype”也是一个对象,它的__proto__指向哪里?

好问题!

在说明“Object prototype”之前,先说一下自定义函数的prototype。自定义函数的prototype本质上就是和 var obj = {} 是一样的,都是被Object创建,所以它的__proto__指向的就是Object.prototype。

但是Object.prototype确实一个特例——它的__proto__指向的是null,切记切记

 

还有——函数也是一种对象,函数也有__proto__吗?

又一个好问题!——当然有。

函数也不是从石头缝里蹦出来的,函数也是被创建出来的。谁创建了函数呢?——Function——注意这个大写的“F”。

且看如下代码。

以上代码中,第一种方式是比较传统的函数创建方式,第二种是用new Functoin创建。

首先根本不推荐用第二种方式

这里只是向大家演示,函数是被Function创建的。

 

好了,根据上面说的一句话——对象的__proto__指向的是创建它的函数的prototype,就会出现:Object.__proto__ === Function.prototype。用一个图来表示。

上图中,很明显的标出了:自定义函数Foo.__proto__指向Function.prototype,Object.__proto__指向Function.prototype,唉,怎么还有一个……Function.__proto__指向Function.prototype?这不成了循环引用了?

对!是一个环形结构。

其实稍微想一下就明白了。Function也是一个函数,函数是一种对象,也有__proto__属性。既然是函数,那么它一定是被Function创建。所以——Function是被自身创建的。所以它的__proto__指向了自身的Prototype。

 

篇幅不少了,估计也都看烦了。快结束了。

最后一个问题:Function.prototype指向的对象,它的__proto__是不是也指向Object.prototype?

答案是肯定的。因为Function.prototype指向的对象也是一个普通的被Object创建的对象,所以也遵循基本的规则。

 

OK 本节结束,是不是很乱?

乱很正常。那这一节就让它先乱着,下一节我们将请另一个老朋友来帮忙,把它理清楚。这位老朋友就是——instanceof。

具体内容,请看下节分解。

---------------------------------------------------------------------------

本文已更新到《深入理解javascript原型和闭包系列》的目录,更多内容可参见《深入理解javascript原型和闭包系列》。

另外,欢迎关注我的微博。

学习作者教程:《前端JS高级面试》《前端JS基础面试题》《React.js模拟大众点评webapp》《zepto设计与源码分析》《json2.js源码解读》

前面提到的上下文环境作用域的知识,除了了解这些知识之外,还是理解的基础。至于“”这个词的概念的文字描述,确实不好解释,我看过很多遍,但是现在还是记不住。但是你只需要知道应用的两种情况即可
说明:该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是其他主流面向对象语言区别最大的两个部分原型,当然,肯定少不了原型作用域
上文(理解javascript原型作用域系列(1一切都是对象已经提到,函数就是对象的一种,因为通过instanceof函数可以判断。varfnfunction(){};consolelog(
“一切都是对象”这句话的重点在于如何去理解“对象”这个概念。当然,也不是所有的都是对象,值类型就不是对象。首先咱们还是先看看javascript中一个常用的运算符typeof。typeof应该
续上一篇文章(http://wwwcnblogscom/wangfupeng1988/p/3986420html的内容。上一篇我们讲到在全局环境下的代码段中,执行上下文环境中有如何数据:变量、函数
在上一篇文章中,介绍了原型的概念,了解到在javascript中构造函数、原型对象、实例三个好基友之间的关系:每一个构造函数都有一个“守护神”原型对象,原型对象心里面也存着一个构造函数的“位置”
原型大家都知道,JavaScript不包含传统的类继承模型,而是使用prototype原型模型。代码实现大概是这样子的functionStudent(name){thisnamename;}varK
构造函数创建对象我们先使用构造函数创建一个对象:functionPerson(){}varperson=newPerson();personname='Kevin';consolelog(person
常用的几种对象创建模式使用new关键字创建最基础的对象创建方式,无非就是其他多数语言一样说的一样:没对象,你new一个呀!vargfnewObject();gfname"tangwei";gfba
参考资料,并强烈推荐:最详尽的JS原型原型链终极详解,没有「可能是」知乎专栏:如何才能通俗易懂的解释javascript里面的‘’?原型:所有对象的_proto_都指向其构造器的prototyp