-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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: