-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
从__proto__和prototype来深入理解JS对象和原型链 #9
Comments
十分感谢 |
会玩! |
@Kelichao 哈哈,欢迎提出见解。 |
相当绕啊,不过终于让我明白透了这关系。 |
再次观摩男神。。再学习一遍 |
这东西感觉要隔一段时间就看,不然很容易被绕迷糊。 typeof Object.prototype === 'object' && (Object.prototype instanceof Object === false)
typeof Function.prototype === 'function' && (Function.prototype instanceof Function === false) |
@simongfxu typeof 这个操作符跟原型链没什么必然的关系. typeof null 还等于 'object'呢. |
get |
为什么我试了一下第一个例子都是返回false,用的是chrome。 |
@igblee 截图看看 |
学习一下 |
我喜欢你画的图,好有感觉。么么哒 |
又被骗进来了吧😄 @Evllis |
@Evllis 忘记从哪偷的图了... 很久很久以前就有这张图了。 Update: 找不到图片具体哪来的,但目前看起来,一个可信的来源是 mollypages.org |
图是从王福朋那里来的 他写的一系列关于原型链的文章,大家伙可以去看看 |
http://www.cnblogs.com/wangfupeng1988/p/4001284.html @bonzstars 是这个吗?前不久刚看完,还得多看几次。 顺便请教博主一个问题:@creeperyang 在JavaScript中,Function构造函数本身也算是Function类型的实例吗? 还有就是JavaScript 里 Function 也算一种基本类型吗?Function继承了Object的所有属性,那为什么还要单独搞个Function,直接在Object延伸,然后其他类型继承Object,非要转个弯。 感觉看了这篇文章,以前的疑问又出来了,就是这个Function.proto === Function.prototype的问题。 |
其实我们可以先看这样一个问题:
这已经某种程度上解开了鸡和蛋的问题: 下面我们来看 似乎可以看出一点东西: 在chrome的console中, 就上图而言,我们有疑惑的其实就是为什么
所以疑惑就可以解除了: 那么问题来了,
下面附加一幅图帮助理解: |
用issue写博客。。。。。这奇葩的方式也是没谁了,用github pages发布个静态博客有那么难? |
@eddiebai 这不是难不难的问题吧,issue 相比 github pages 更加方便吧... |
你们怎么都来得这么快?都睡在GayHub里面吗?@rccoder |
@jawil 邮件会 push 啊... |
@waterVenice7 我当然没有搞错。一个最简单的例子: const parent = { x: 1 };
const child = Object.create(parent); 对 如果你有一些其它面向对象语言的基础,那么问出这个问题是比较自然的,因为对Java/C++之类的语言来说,类(class)和实例(instance)就是完全不同的两个概念。它通过类的继承来实现继承。 但是,对JavaScript而言,它没有类(class)和实例(instance)的区别,它只有对象(object)。它通过原型链来实现继承(指定某个对象的原型对象 |
看到这里,关于鸡蛋问题我的唯一疑问就是,
验证了一下,果然是这样: Object.prototype instanceof Object // false
Object.prototype instanceof Function // false 所以,大概回答就是, 自荐几篇博客,记录了对原型这个技术问题的思考哟: |
只能说,在JS的世界里,先有Object.prototype后有天,然后有了Function.prototype,接着就有了Function,Object等等 |
写的非常好,理清了我的思路。 |
所以鸡蛋的问题是通过规定解决的么: |
真实的世界不知道,但是计算机的世界回到最开始的地方就是通过规定解决的吧 |
你用Function.prototype 去和一个不存在的Function.proto去做比较,得出false,然后说博主有问题?并且说出 权威指南这本书很烂,还说博主用github写博文是为了吸星。 |
原来这个原型链这么深奥。。 |
勘误:”Function也是对象,继承了Object.prototype“,应改为"Function.prototype也是对象,继承了Object.prototype" |
Thank you for your e-mail!I'll hasten to deal with it.
谢谢您的邮件,我将尽快处理。
|
Nice,thank you! ——weihong
|
讲的太好啦! |
Thank you for your e-mail!I'll hasten to deal with it.
谢谢您的邮件,我将尽快处理。
|
已收到,稍候会处理best wish~
|
就标题而言,这是七八篇里起得最满意的,高大上,即使外行人也会不明觉厉! 😂
不过不是开玩笑,本文的确打算从
__proto__
和prototype
这两个容易混淆来理解JS的终极命题之一:对象与原型链。__proto__
和prototype
__proto__
引用《JavaScript权威指南》的一段描述:
翻译出来就是每个JS对象一定对应一个原型对象,并从原型对象继承属性和方法。好啦,既然有这么一个原型对象,那么对象怎么和它对应的?
对象
__proto__
属性的值就是它所对应的原型对象:上面的代码应该已经足够解释清楚
__proto__
了:grin:。好吧,显然还不够,或者说带来了新的问题:Object.prototype
是什么?凭什么说one
和two
的原型就是Object.prototype
?prototype
首先来说说
prototype
属性,不像每个对象都有__proto__
属性来标识自己所继承的原型,只有函数才有prototype
属性。为什么只有函数才有
prototype
属性?ES规范就这么定的。开玩笑了,其实函数在JS中真的很特殊,是所谓的_一等公民_。JS不像其它面向对象的语言,它没有类(
class
,ES6引进了这个关键字,但更多是语法糖)的概念。JS通过函数来模拟类。当你创建函数时,JS会为这个函数自动添加
prototype
属性,值是空对象值是一个有 constructor 属性的对象,不是空对象。而一旦你把这个函数当作构造函数(constructor
)调用(即通过new
关键字调用),那么JS就会帮你创建该构造函数的实例,实例继承构造函数prototype
的所有属性和方法(实例通过设置自己的__proto__
指向承构造函数的prototype
来实现这种继承)。小结
虽然对不熟悉的人来说还有点绕,但JS正是通过
__proto__
和prototype
的合作实现了原型链,以及对象的继承。构造函数,通过
prototype
来存储要共享的属性和方法,也可以设置prototype
指向现存的对象来继承该对象。对象的
__proto__
指向自己构造函数的prototype
。obj.__proto__.__proto__...
的原型链由此产生,包括我们的操作符instanceof
正是通过探测obj.__proto__.__proto__... === Constructor.prototype
来验证obj
是否是Constructor
的实例。回到开头的代码,
two = new Object()
中Object
是构造函数,所以two.__proto__
就是Object.prototype
。至于one
,ES规范定义对象字面量的原型就是Object.prototype
。更深一步的探讨
我们知道JS是单继承的,
Object.prototype
是原型链的顶端,所有对象从它继承了包括toString
等等方法和属性。Object
本身是构造函数,继承了Function.prototype
;Function
也是对象,继承了Object.prototype
。这里就有一个_鸡和蛋_的问题:什么情况下会出现鸡和蛋的问题呢?就是声明一个包含所有集合的集合啊!好了,你们知道这是罗素悖论,但并不妨碍PL中这样设计。
那么具体到JS,ES规范是怎么说的?
以上均翻译自http://www.ecma-international.org/ecma-262/5.1/#sec-15,_鸡和蛋_的问题就是这么出现和设计的:**`Function`继承`Function`本身,`Function.prototype`继承`Object.prototype`。**
一张图和总结
Update: 图片来自 mollypages.org
相信经过上面的详细阐述,这张图应该一目了然了。
Function.prototype
和Function.__proto__
都指向Function.prototype
,这就是鸡和蛋的问题怎么出现的。Object.prototype.__proto__ === null
,说明原型链到Object.prototype
终止。The text was updated successfully, but these errors were encountered: