轉載自Function和Object 應該知道的
javascript有5種基礎的內建物件(Fundamental Objects),Object
、Function
、Error
、Symbol
、Boolean
,而Object
/Function
尤為特殊,是定義其他內建物件或者普通物件和方法的基礎。
詳細的瞭解Object
和Function
物件有助於更好的理解javascript的一些工作原理。
和其他引用型別一樣,Object
/Function
既是物件,有自己的方法和屬性,也是函式,可以作為建構函式。
本文主要討論以下幾個問題:
Fucntion.prototype
和普通物件的prototype
有何區別?Object.prototype.__proto__
= ?Object.__proto__
= ?Object
、Function
的原型物件有何特殊之處?
Function
Function的屬性
在ES6標準中,Function 物件有兩個屬性:
-
length 值為1,這個屬性的特性為
{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }
,即不可覆蓋,不可被for...in
遍歷,但可以通過Object.defineProperty
修改它的上面這些特性 -
prototype 為原型物件,(見ES最新標準說明 Function.prototpye)它跟一般函式的
prototype
的區別在於- ❗️它不可寫,不可配置,不可遍歷。 即它永遠指向固定的一個物件,且是其他所有函式的原型物件,所有函式本身的
__proto__
指向它。
const o = {number: 20} Function.prototype = o // 依然是原來的值,未改變
typeof Array.proto // 'function' [=== Function.prototype] typeof Object.proto // 'function' [=== Function.prototype]
typeof Array.prototype.proto // 'object' [=== Object.prototype]
function F () {} F.proto === Function.prototype // true
複製程式碼F.prototype = o // prototype指向o 複製程式碼
- ❗️它是一個函式。 一般函式的
prototype
是一個帶有constructor
屬性的普通物件,但Function
的prototype
是一個函式物件(built-in function object
),是js
中唯一一個預設prototype
為函式的物件
typeof Function.prototype // 'function' 複製程式碼
function F () {} typeof F.prototype // ☘ 'object' typeof Object.prototype // 'object' 複製程式碼
- ❗️它不可寫,不可配置,不可遍歷。 即它永遠指向固定的一個物件,且是其他所有函式的原型物件,所有函式本身的
這是ES標準中規定的Function
物件的兩個屬性,但其實在FireFox、Chrome在實現時,還有一個name
屬性,它的值就是'Function'
★ Function.prototype
在ES規範,有關Function.prototype部分 定義的Function
的prototype
的方法有
Function.prototype.apply
Function.prototype.bind
Function.prototype.call
Function.prototype.contructor
Function.prototype.toString
Function.prototype[@@hasInstance](V)
複製程式碼
函式和物件都有__proto__
屬性,指向建構函式的prototype
屬性所指向的物件,即它的原型物件。
任何函式作為Function
的例項,本身帶有__proto__
屬性(❗️並非它的原型物件prototype
上的__proto__
屬性)指向Function.prototype
,所以Function.prototype
上的屬性和方法都會被函式物件(function object)所繼承。下面是幾個有意思的等式
Function.__proto__ === Function.prototype // true ❗️
Object.__proto__ === Function.prototype // true
Object.prototype.__proto__ === null // true
Function.prototype.__proto__ === Object.prototype // true
Object.prototype === Object.__proto__ // false
複製程式碼
同時,因為函式物件本身有prototype
屬性,是Object
的例項,所以也繼承了Object.prototype
的屬性。
Object
★ Object函式物件的屬性
Object
作為函式,與普通函式一樣,有length
、prototype
、__proto__
、name
屬性,除此之外,還有很多沒有被繼承的私有方法
// 方法
Object.assign()
Object.create()
Object.defineProperties()
Object.defineProperty()
Object.entries()
Object.freeze()
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.getPrototypeOf()
Object.is()
Object.isExtensible()
Object.isFrozen()
Object.isSealed()
Object.keys()
Object.preventExtensions()
Object.seal
Object.setPrototypeOf()
Object.values()
複製程式碼
Object
函式物件的方法不是這裡的重點,就不再展開。
★ Object.prototype
與Function.prototype
和其他引用型別(Array.prototype
、String.prototype
)一樣是不可寫、不可配置、不可for...in遍歷的,但依然可以被擴充套件,即可以往Object.prototype
新增屬性和方法
Object.isExtensible(Object.prototype) // true
複製程式碼
- ❗️
Object.prototype
的一個重要特性是,它是所有物件原型鏈的終點,因為Object.prototype.__proto__
的值為null
,即
Object.prototype.__proto__ === null
複製程式碼
一個物件的例項,沿著它的原型鏈,通過__proto__
一層層往上找某一個屬性,如果在Object.prototype
上沒找到,那就會返回undefined
,所以,原型鏈不會無限的找下去。
function F () {}
F.prototype.age = 20
let f = new F()
f.__proto__ === F.prototype // true
f.__proto__.__proto__ === Object.prototype //true
f.__proto__.proto__.__proto__ === null // true
/**
複製程式碼
- 查詢過程
- f.color -> 沒找到,繼續
- f.proto.color(F.prototype) -> 沒找到,繼續
- f.proto.proto.color(F.prototype.proto,Object.prototype) 沒找到,返回undefined 複製程式碼
如果繼續 f.proto.proto.proto (Object.prototype.proto) === null 結果跟上面一樣 */ console.log(f.color) // undefined 複製程式碼
Object.prototype
上的屬性和方法,會被js中的所有方法和物件所繼承,ES規範中的屬性
Object.prototype.constructor
Object.prototype.hasOwnProperty()
Object.prototype.isPrototypeOf()
Object.prototype.propertyIsEnumerable()
Object.prototype.toLocaleString()
Object.prototype.toString()
Object.prototype.valueOf()
Object.prototype.__proto__
複製程式碼
下圖是Function
、Object
與Function.prototype
、Object.prototye
相互之間關係圖
Object、Function的關係
Object
和Function
之間最讓人琢磨不透的,就是他們的關係
Object instanceof Object // true
Object instanceof Function // true
Function instanceof Function // true
Function instanceof Object // true
const o = {}
o instanceof Object //true
o instanceof Function // false
複製程式碼
function F () {}
F instanceof Object //true
F instanceof Function //true
複製程式碼
未完待續 ~~~