日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

object htmldivelement什么意思_深入探究 Function amp; Object 鸡蛋问题

發布時間:2025/3/12 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 object htmldivelement什么意思_深入探究 Function amp; Object 鸡蛋问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(給前端樹加星標,提升前端技能)

轉自:高級前端進階

引言

上篇文章用圖解的方式向大家介紹了原型鏈及其繼承方案,在介紹原型鏈繼承的過程中講解原型鏈運作機制以及屬性遮蔽等知識,今天這篇文章就來深入探究下 Function.__proto__ === Function.prototype 引起的雞生蛋蛋生雞問題,并在這個過程中深入了解 Object.prototype、Function.prototype、function Object 、function Function 之間的關系。

Object.prototype

我們先來看看 ECMAScript 上的定義(15.2.4)。

The value of the [[Prototype]] internal property of the Object prototype object is null, the value of the [[Class]] internal property is "Object", and the initial value of the [[Extensible]] internal property is true.

Object.prototype 表示 Object 的原型對象,其 [[Prototype]] 屬性是 null,訪問器屬性 __proto__ 暴露了一個對象的內部 [[Prototype]] 。 Object.prototype 并不是通過 Object 函數創建的,為什么呢?看如下代碼

function Foo() {this.value = 'foo'; } let f = new Foo(); f.__proto__ === Foo.prototype; // true

實例對象的 __proto__ 指向構造函數的 prototype,即 f.__proto__ 指向 Foo.prototype,但是 Object.prototype.__proto__ 是 null,所以 Object.prototype 并不是通過 Object 函數創建的,那它如何生成的?其實 Object.prototype 是瀏覽器底層根據 ECMAScript 規范創造的一個對象。

Object.prototype 就是原型鏈的頂端(不考慮 null 的情況下),所有對象繼承了它的 toString 等方法和屬性。

Function.prototype

我們先來看看 ECMAScript 上的定義(15.3.4)。

The Function prototype object is itself a Function object (its [[Class]] is "Function").
The value of the [[Prototype]] internal property of the Function prototype object is the standard built-in Object prototype object.
The Function prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the Object prototype Object.

Function.prototype 對象是一個函數(對象),其 [[Prototype]] 內部屬性值指向內建對象 Object.prototype。Function.prototype 對象自身沒有 valueOf 屬性,其從 Object.prototype 對象繼承了valueOf 屬性。

Function.prototype 的 [[Class]] 屬性是 Function,所以這是一個函數,但又不大一樣。為什么這么說呢?因為我們知道只有函數才有 prototype 屬性,但并不是所有函數都有這個屬性,因為 Function.prototype 這個函數就沒有。

Function.prototype // ? () { [native code] }Function.prototype.prototype // undefined

當然你會發現下面這個函數也沒有 prototype 屬性。

let fun = Function.prototype.bind() // ? () { [native code] }fun.prototype // undefined

為什么沒有呢,我的理解是 Function.prototype 是引擎創建出來的函數,引擎認為不需要給這個函數對象添加 prototype 屬性,不然 Function.prototype.prototype… 將無休無止并且沒有存在的意義。

function Object

我們先來看看 ECMAScript 上的定義(15.2.3)。

The value of the [[Prototype]] internal property of the Object constructor is the standard built-in Function prototype object.

Object 作為構造函數時,其 [[Prototype]] 內部屬性值指向 Function.prototype,即

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

使用 new Object() 創建新對象時,這個新對象的 [[Prototype]] 內部屬性指向構造函數的 prototype 屬性,對應上圖就是 Object.prototype。

當然也可以通過對象字面量等方式創建對象。

  • 使用對象字面量創建的對象,其 [[Prototype]] 值是 Object.prototype。
  • 使用數組字面量創建的對象,其 [[Prototype]] 值是 Array.prototype。
  • 使用 function f(){} 函數創建的對象,其 [[Prototype]] 值是 Function.prototype。
  • 使用 new fun() 創建的對象,其中 fun 是由 JavaScript 提供的內建構造器函數之一(Object, Function, Array, Boolean, Date, Number, String 等等),其 [[Prototype]] 值是 fun.prototype。
  • 使用其他 JavaScript 構造器函數創建的對象,其 [[Prototype]] 值就是該構造器函數的 prototype 屬性。
let o = {a: 1}; // 原型鏈: o ---> Object.prototype ---> nulllet a = ["yo", "whadup", "?"]; // 原型鏈: a ---> Array.prototype ---> Object.prototype ---> nullfunction f(){return 2; } // 原型鏈: f ---> Function.prototype ---> Object.prototype ---> nullvar fun = new Function(); // 原型鏈: fun ---> Function.prototype ---> Object.prototype ---> nullfunction Foo() {return {}; } let foo = new Foo(); // 原型鏈: foo ---> Foo.prototype ---> Object.prototype ---> null

function Function

我們先來看看 ECMAScript 上的定義(15.3.3)。

The Function constructor is itself a Function object and its [[Class]] is "Function". The value of the [[Prototype]] internal property of the Function constructor is the standard built-in Function prototype object.

Function 構造函數是一個函數對象,其 [[Class]] 屬性是 Function。Function 的 [[Prototype]] 屬性指向了 Function.prototype,即

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

到這里就有意思了,我們看下雞生蛋蛋生雞問題。

Function & Object 雞蛋問題

我們看下面這段代碼

Object instanceof Function // true Function instanceof Object // trueObject instanceof Object // true Function instanceof Function // true

Object 構造函數繼承了 Function.prototype,同時 Function 構造函數繼承了Object.prototype。這里就產生了 雞和蛋 的問題。為什么會出現這種問題,因為 Function.prototype 和 Function.__proto__ 都指向 Function.prototype。

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

對于 Function.__proto__ === Function.prototype 這一現象有 2 種解釋,爭論點在于 Function 對象是不是由 Function 構造函數創建的一個實例?

解釋 1、YES:按照 JavaScript 中“實例”的定義,a 是 b 的實例即 a instanceof b 為 true,默認判斷條件就是 b.prototype 在 a 的原型鏈上。而 Function instanceof Function 為 true,本質上即 Object.getPrototypeOf(Function) === Function.prototype,正符合此定義。

解釋 2、NO:Function 是 built-in 的對象,也就是并不存在“Function對象由Function構造函數創建”這樣顯然會造成雞生蛋蛋生雞的問題。實際上,當你直接寫一個函數時(如 function f() {} 或 x => x),也不存在調用 Function 構造器,只有在顯式調用 Function 構造器時(如 new Function('x', 'return x') )才有。

我個人偏向于第二種解釋,即先有 Function.prototype 然后有的 function Function() ,所以就不存在雞生蛋蛋生雞問題了,把 Function.__proto__ 指向 Function.prototype 是為了保證原型鏈的完整,讓 Function 可以獲取定義在 Object.prototype 上的方法。

最后給一個完整的圖,看懂這張圖原型就沒問題了。

內置類型構建過程

JavaScript 內置類型是瀏覽器內核自帶的,瀏覽器底層對 JavaScript 的實現基于 C/C++,那么瀏覽器在初始化 JavaScript 環境時都發生了什么?

沒找到官方文檔,下文參考自 https://segmentfault.com/a/1190000005754797。對于其觀點比較認同,歡迎小伙伴提出不同觀點。

1、用 C/C++ 構造內部數據結構創建一個 OP 即 (Object.prototype) 以及初始化其內部屬性但不包括行為。

2、用 C/C++ 構造內部數據結構創建一個 FP 即 (Function.prototype) 以及初始化其內部屬性但不包括行為。

3、將 FP 的 [[Prototype]] 指向 OP。

4、用 C/C++ 構造內部數據結構創建各種內置引用類型。

5、將各內置引用類型的[[Prototype]]指向 FP。

6、將 Function 的 prototype 指向 FP。

7、將 Object 的 prototype 指向 OP。

8、用 Function 實例化出 OP,FP,以及 Object 的行為并掛載。

9、用 Object 實例化出除 Object 以及 Function 的其他內置引用類型的 prototype 屬性對象。

10、用 Function 實例化出除Object 以及 Function 的其他內置引用類型的 prototype 屬性對象的行為并掛載。

11、實例化內置對象 Math 以及 Grobal

至此,所有內置類型構建完成。

參考

從探究Function.__proto__===Function.prototype過程中的一些收獲
高能!typeof Function.prototype 引發的先有 Function 還是先有 Object 的探討
從__proto__和prototype來深入理解JS對象和原型鏈

覺得本文對你有幫助?請分享給更多人

關注「前端樹」加星標,提升前端技能

喜歡就點一下「在看」唄~

總結

以上是生活随笔為你收集整理的object htmldivelement什么意思_深入探究 Function amp; Object 鸡蛋问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。