javascript的兩類對象:1、宿主對象(host Objects),是由JavaScript宿主環境提供的對象,它們的行為完全由宿主環境決定;2、內建對象(Built-in Objects),是由JavaScript語言提供的物件。
本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
在javascript中,可以把物件分成兩類宿主物件和內建物件。
宿主物件(host Objects):由 JavaScript 宿主環境提供的對象,它們的行為完全由宿主環境決定。
內建物件(Built-in Objects):由JavaScript 語言提供的物件
固有物件(Intrinsic Objects ):由標準規定,隨著JavaScript 執行時期建立而自動建立的物件實例。
原生物件(Native Objects):可以由使用者透過 Array、RegExp 等內建建構器或特殊語法建立的物件。
普通物件(Ordinary Objects):由{}語法、Object 建構器或 class 關鍵字定義類別所建立的對象,它能夠被原型繼承。
JavaScript 宿主物件千奇百怪,但前端最熟悉的無疑是瀏覽器環境中的宿主了。在瀏覽器環境中,我們都知道全域物件是 window,window 上又有許多屬性,例如 document。實際上,這個全域物件 window 上的屬性,一部分來自 JavaScript 語言,一部分來自瀏覽器環境。 JavaScript 標準中規定了全域物件屬性,W3C 的各種標準中規定了 Window 物件的其它屬性。宿主物件也分為固有的和使用者可建立的兩種,例如 document.createElement 就可以建立一些 DOM 物件。宿主也會提供一些建構器,例如我們可以使用new Image 來創建img 元素,
#固有物件是由標準規定,隨著JavaScript 運行時創建而自動建立的物件實例。固有物件在任何 JavaScript 程式碼執行前就已經被創建出來了,它們通常扮演者類似基礎函式庫的角色。我們前面提到的「類別」其實就是固有物件的一種。 ECMA 標準為我們提供了一份固有物件表,裡面含有 150 個固有物件。
我們把 JavaScript 中,能夠透過語言本身的建構器所建立的物件稱為原生物件。在 JavaScript 標準中,提供了 30 多個建構器。依照我的理解,依照不同應用場景,我把原生物件分成了以下幾種種類。
透過這些建構器,我們可以用 new 運算建立新的對象,所以我們把這些物件稱為原生物件。幾乎所有這些建構器的能力都是無法用純 JavaScript 程式碼實現的,它們也無法用 class/extend 語法來繼承。這些建構器所建立的物件多數使用了私有欄位, 例如:
Error: [[ErrorData]] Boolean: [[BooleanData]] Number: [[NumberData]] Date: [[DateValue]] RegExp: [[RegExpMatcher]] Symbol: [[SymbolData]] Map: [[MapData]]
這些欄位使得原型繼承方法無法正常運作,所以,我們可以認為,所有這些原生物件都是為了特定能力或效能,而設計出來的「特權物件」。
我在前面介紹了物件的一般分類,在JavaScript 中,還有一個看待物件的不同視角,這就是用物件來模擬函數和建構器。事實上,JavaScript 為這一類物件預留了私有欄位機制,並規定了抽象的函數物件與建構器物件的概念。
函數物件的定義是:具有[[call]]私有欄位的對象,建構器物件的定義是:具有私有欄位[[construct]]的物件。
JavaScript 以物件模擬函數的設計取代了一般程式語言中的函數,它們可以像其它語言的函數一樣被呼叫、傳參。任何宿主只要提供了“具有[[call]]私有欄位的物件”,就可以被 JavaScript 函數呼叫語法支援。
我們可以這樣說,任何對像只需要實作[[call]],它就是一個函數對象,可以去當函數被呼叫。而如果它能實現[[construct]],它就是一個構造器對象,可以作為構造器被呼叫。
對於提供 JavaScript 運作環境的程式設計師來說,只要欄位符合,我們在上文中提到的宿主物件和內建物件(如 Symbol 函數)可以模擬函數和建構器。
當然了,使用者用 function 關鍵字建立的函數必定同時是函數和建構器。不過,它們所表現出來的行為效果卻不相同。
對於宿主和內建物件來說,它們實作[[call]](作為函數被呼叫)和[[construct]](作為建構器被呼叫)不總是一致的。
对于用户使用 function 语法或者 Function 构造器创建的对象来说,[[call]]和[[construct]]行为总是相似的,它们执行同一段代码。我们看一下示例。
function f(){ return 1; } var v = f(); //把f作为函数调用 var o = new f(); //把f作为构造器调用
这样的规则造成了个有趣的现象,如果我们的构造器返回了一个新的对象,那么 new 创建的新对象就变成了一个构造函数之外完全无法访问的对象,这一定程度上可以实现“私有”。
function cls(){ this.a = 100; return { getValue:() => this.a } } var o = new cls; o.getValue(); //100 //a在外面永远无法访问到
除了上面介绍的对象之外,在固有对象和原生对象中,有一些对象的行为跟正常对象有很大区别。
它们常见的下标运算(就是使用中括号或者点来做属性访问)或者设置原型跟普通对象不同,这里我简单总结一下。
Array:Array 的 length 属性根据最大的下标自动发生变化。
Object.prototype:作为所有正常对象的默认原型,不能再给它设置原型了。
String:为了支持下标运算,String 的正整数属性访问会去字符串里查找。
Arguments:arguments 的非负整数型下标属性跟对应的变量联动。
模块的 namespace 对象:特殊的地方非常多,跟一般对象完全不一样,尽量只用于 import 吧。
类型数组和数组缓冲区:跟内存块相关联,下标运算比较特殊。
bind 后的 function:跟原来的函数相关联。
【相关推荐:javascript视频教程】
以上是javascript物件分為哪兩大類的詳細內容。更多資訊請關注PHP中文網其他相關文章!