Code Monkey home page Code Monkey logo

Comments (25)

 avatar commented on August 24, 2024 16

Function.__proto__ === Function.prototype,很简单的,函数是Function的实例,每一个实例内部都有一个属性__proto__指向该构造函数的prototype,恰巧Function本身就一个函数 function Function() {}

from blog.

mqyqingfeng avatar mqyqingfeng commented on August 24, 2024 9

了解了本质,开发的时候很多问题才能解决得更加灵活、优雅。

from blog.

jawil avatar jawil commented on August 24, 2024

其实深究这种问题开发没多大用处,但是探寻事物的本质却收获不少。

from blog.

chenshiforever avatar chenshiforever commented on August 24, 2024

之前一直以为prototype属性一定是对象,直到发现了有Function.prototype这个东西。实际上呢,这句话‘Function对象是由Function构造函数创建的一个实例’,为了记住原型链里面的关系,按照这句话来记得话是没有毛病的,但是深究Function是一个内置对象也是没有毛病的。我是看见ES6的class的继承回过头来看这里的,因为ES6,里边的一个继承 B.__proto__= A,这里不符合我之前所理解的所有的prototype都是对象这一个理论。纠结了好几天。还有,Object.prototype中的Object到底是哪来的,这个问题我发现也被绕进去了。

from blog.

Ghohankawk avatar Ghohankawk commented on August 24, 2024

我觉的你最后提的4个问题,我也是想知道具体为啥如此,不过以下是我的个人理解,可能有误:
第一个是说Object,这个名词,可能就是你说的v8引擎创建的默认对象,而把它起名为了object
第二个,好像就应该说,为啥说,函数就是对象,等号左边是,Function这个对象,而右边是Function这个函数,同名函数和对象
第三个,就是如下:
Object.proto==Function.prototype,因此,Object是Function的实例,
而Function.proto.proto==Object.prototype,Function是Object的实例
这刚好解释了,为啥,函数是一种特殊的对象,对象又是构造函数产生的,这种死循环
第四个,为啥这么设计我,也不太明白,可能是,其他的都是对象,那么怎么区分函数和对象?因为不说第三条吗?函数就是对象,对象即是函数,要细分的时候,总的有分区吧,
比如,我们一般认为Object,就是个对象,不说函数,而Function默认都是认为函数,不说是对象

from blog.

zhoubhin avatar zhoubhin commented on August 24, 2024

@jawil @Ghohankawk 这四个问题问得很深奥,啊不,很有深度(手动滑稽)
1、天知道Object.prototype的Object到底指代什么
2、Function.proto===Function.prototype成立。既是也不是。
是:从原型链上看,Function对象的prototype是在Function构造函数的原型链上的,实例的说法成立。
不是:Function是内建对象,如果说Function对象是Function构造函数创建,那Function构造函数又是谁创建的呢?
3、先有Object.prototype(原型链顶端),Function.prototype继承Object.prototype而产生,最后,Function和Object和其它构造函数继承Function.prototype而产生。详见:
creeperyang/blog#9
http://louiszhai.github.io/2015/12/17/prototype/
4、我觉得是为了更好地从字面意思上去区分,看到Object就知道是某个对象,看到Function就知道是某个函数,不然,看到Function,想到的是既是对象又是函数,那该如何去用?

from blog.

OSInsight avatar OSInsight commented on August 24, 2024

Function.__proto__ === Function.prototype,很简单的,函数是Function的实例,每一个实例内部都有一个属性__proto__指向该构造函数的prototype,恰巧Function本身就一个函数 function Function() {}

每一个实例内部都有一个属性__proto__指向该构造函数的prototype

let a = [];
a.__proto__ === Array.prototype
// true
Array.__proto__ === Function.prototype
// true
Array.prototype.__proto__ === Object.prototype // 实例 Array.prototype
// true
a.constructor === Array
// true
Array.constructor === Function
// true
Array.prototype.constructor === Array  // 构造函数的prototype? --> Object
// true

from blog.

GHolk avatar GHolk commented on August 24, 2024

我是認為 js runtime 中物件就是有一個 __proto__ 屬性,
在查詢屬性時就會一路用 proto 往上找。
函數可以當作建構函數,只是方便我們建立同類的物件;
並在建構物件時,把 proto 指向建構式的 prototype 屬性。

這些都只是包裝。
Object 與 Object.prototype 沒什麼特殊意義,
他只是提供了一些物件常用的方法,
而那些方法其實都能自己 patch 出來。
所以你大可自己寫一個 MyObject 建構式,
在 MyObject.prototype 上也可以自幹出
多數 Object.prototype 提供的方法。

唯一特例是 Function ,
Function.prototype 不是物件,
而也是函數;我不確定這有什麼意義。
但函數也是一種物件,可以有擁有屬性與原型,
所以 Function.prototype.proto == Object.prototype 。

關於 es6 新增的箭頭函數、generator 、 async function ,
其中箭頭函數的原型也是指向 Function.prototype ,
和一般函數沒有差別。

而 generator 與 async 就有趣了,
他們的建構函數不是公開的全域變數,
要用 (function*(){}).constructor(async function() {}).constructor 來獲取。
(以下稱為 GeneratorFunction 與 AsyncFunction 。)

這二個建構式也都和 Function 一樣能用來動態建構函數,
他們的實例的原型是各自建構子的 .prototype
*.prototype 的原型又指向 Function.prototype ,
所以 instanceof 可以得到正確的結果。

但又一點很吊詭, GeneratorFunction 與 AsyncFunction
原型不是指向 Function.prototype 。
原本 js 中所有函數包括建構函數的原型都是指向 Function.prototype ,
但 GeneratorFunction 與 AsyncFunction 的原型是指向 Function 。
GeneratorFunction.__proto__ == Function

後來我發現這可能是 es6 class 的緣故。
如果用 es6 class 語法繼承現有類別,
雖然子 constructor 仍是函數,
constructor.__proto__ 會指向父建構式。

class SubObject extends Object {
}
SubObject.prototype instanceof Object.prototype // true
SubObject instanceof Object // true
SubObject.entries == Object.entries // true

目前想到的二個原因:

  1. 讓 instanceof 算符可以運作在 class 上,也就是建構函數上。
    比較好看而已。
  2. 讓子類繼承父類的靜態方法。因為原型指向了父類,自然能從子類存取到父類的屬性。

所以 GeneratorFunction 與 AsyncFunction 在內部
應該是用類似 class extends Function 的方法實作的。

結論

我認為 js 中的函數與物件都是一個黑箱,
那些建構式只是其一個很有限的介面,
提供很少的方法讓我們接觸外部。

而函數又比物件更黑,
相比物件只是簡單的 key value 集合,
加上一個 __proto__ 屬性。
基本上是可以自己實現的。

child.get = function (key) {
  if (this.hasOwn(key)) return this.getOwn(key)
  else if (this.parent) return this.parent.get(ket)
  else return undefined  // parent is null

但函數的閉包、this 、yield await 都是透過黑魔法實現的功能,
需要在執行時做很多手腳才能辦到,
不然就是像 babel 要完全重編譯成另一種樣子。


今年早些做了點有趣的功能,像 自己實現 Promise
用 generator 實現 async 函數
所以研究了一下要怎麼為 generator function 加 method 但又不加到所有 function 上,
所以找到了 GeneratorFunction.prototype 這東西,
順便做了點實驗。

(結論是 async 可以透過 generator 實現,promise 可以以原生物件方式實現;
整個 async 與 promise 系列升級,只有 generator 是真正重要不可取代的元件。)

昨天才看到這篇,覺得也是另一種探討方向,
也想把自己的想法與發現寫下來,就寫了。
(發現 AsyncFunction.__proto__ != Function.prototype 。)
沒想到寫到一半忽然想通是 es6 class extends 的原因,
文章長度幾乎加倍……。

from blog.

OSInsight avatar OSInsight commented on August 24, 2024

Function.__proto__ === Function.prototype,很简单的,函数是Function的实例,每一个实例内部都有一个属性__proto__指向该构造函数的prototype,恰巧Function本身就一个函数 function Function() {}

每一个实例内部都有一个属性__proto__指向该构造函数的prototype

let a = [];
a.__proto__ === Array.prototype
// true
Array.__proto__ === Function.prototype
// true
Array.prototype.__proto__ === Object.prototype // 实例 Array.prototype
// true
a.constructor === Array
// true
Array.constructor === Function
// true
Array.prototype.constructor === Array  // 构造函数的prototype? --> Object
// true
// 1.构造函数创建实例。实例一创造出来就有constructor属性(指向构造函数)和__proto__属性(指向原型对象)
let a = [];
a.constructor === Array // true
a.__proto__ === Array.prototype // true
Array.constructor === Function // true
Array.__proto__ === Function.prototype // true
Function.constructor === Function // true
Function.__proto__ === Function.prototype // true
Object.constructor === Function // true
Object.__proto__ === Function.prototype // true
// 2.构造函数对应有原型对象,有constructor属性(指向构造函数)和__proto__属性(指向原型链上级)
Array.prototype.constructor === Array // true
Array.prototype.__proto__ === Object.prototype //true
Function.prototype.constructor === Function // true
Function.prototype.__proto__ === Object.prototype // true
Object.prototype.constructor === Object //true
Object.prototype.__proto__ === null // true

from blog.

aiyogg avatar aiyogg commented on August 24, 2024

偶然在控制台输入 Function.prototype发现是函数类型,然后找到了这篇文章。收获良多,感谢博主。

from blog.

hezhongfeng avatar hezhongfeng commented on August 24, 2024

@DOTA2mm
其实Object,String,Number等等都是构造函数,刀友你好

from blog.

aiyogg avatar aiyogg commented on August 24, 2024

@DOTA2mm
其实Object,String,Number等等都是构造函数,刀友你好

你好你好~ 😃
hezfblog 很赞!

from blog.

hezhongfeng avatar hezhongfeng commented on August 24, 2024

@DOTA2mm
其实Object,String,Number等等都是构造函数,刀友你好

你好你好~ 😃
hezfblog 很赞!

加个好友啊?老年刀狗
130128931

from blog.

aiyogg avatar aiyogg commented on August 24, 2024

@DOTA2mm
其实Object,String,Number等等都是构造函数,刀友你好

你好你好~ 😃
hezfblog 很赞!

加个好友啊?老年刀狗
130128931

👌

from blog.

Jancat avatar Jancat commented on August 24, 2024

Function.__proto__ === Function.prototype 导致 Function.constructor === Function,即: Function 是它自己的构造函数

引用自 http://www.mollypages.org/tutorials/js.mp

from blog.

zhangenming avatar zhangenming commented on August 24, 2024

Function.prototype()
为什么可以直接执行 执行结果是什么?
typeof Function.prototype 结果是function
Function.prototype instanceof Function 结构false

from blog.

panchengtao avatar panchengtao commented on August 24, 2024

所以这就是为什么Javascript是个蛋疼和优雅的东西,各种意义不清的东西,却能强行解释到一起

from blog.

ftchan avatar ftchan commented on August 24, 2024

我的理解是这样:

  • 普通对象的原型根源是 Object.prototype ,而 Object.prototype 的最终根源是 null
  • 函数对象(Array、Number、Date、Object等等、包括 Function)它们的原型都继承于 Function.prototype,同时 Function 对象会从自己的原型上获得一些方法,比如 applycallbind 等等。(具体的可以看MDN)。

Object 和 Function 的原型是两条线:

Function -> Function.prototype -> Object.prototype -> null
Object -> Function.prototype -> Object.prototype -> null

它们之间没有形成闭环回路,而是一种类似互相继承。因为互相继承,Function 和 Object 就可以共享对方的原型方法。

from blog.

BenjaminFF avatar BenjaminFF commented on August 24, 2024

其实深究这种问题开发没多大用处,但是探寻事物的本质却收获不少。

image
这里有问题。。。应该是原型

from blog.

luo-boss avatar luo-boss commented on August 24, 2024

你好

from blog.

foolishway avatar foolishway commented on August 24, 2024

也有此疑问,既然 Function instanceof Object === true,为什么Function.__proto__ !== Object.prototype ?

from blog.

cheungkin24 avatar cheungkin24 commented on August 24, 2024

也有此疑问,既然 Function instanceof Object === true,为什么Function.__proto__ !== Object.prototype ?

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

from blog.

mango-csl avatar mango-csl commented on August 24, 2024

from blog.

chuanHH avatar chuanHH commented on August 24, 2024

from blog.

xiaoyan13 avatar xiaoyan13 commented on August 24, 2024

个人理解:
模型:
image
模型解释:每个函数(是不是构造函数都可,除了箭头)都唯一对应一个原型对象,根据该函数创建的实例指向该原型对象。

设构造函数 Object 的原型对象是 A,构造函数 Function 的原型对象是 B.

规定:默认下,所有的函数的 原型对象 均指向 A。
此规定在原型链顶端存在唯一例外: 函数 Object 的 原型对象 指向 B.
这构成循环:
image
最后可以发现,这个完整的循环链从下往上,只有 Fucntion 函数没有画出它的__proto__指向谁。

这是因为,Function 函数是 Function 函数自身的实例。之所以这样设计:
我们假设 Function 是某个函数的实例,那它只能是 Fucntion 的实例了;
我们假设 Funciton 不是任何函数的实例:js 规定任何对象都存在__proto__,该假设不成立。
image

from blog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.