- 看透JavaScript:原理、方法與實踐
- 韓路彪
- 2218字
- 2020-11-28 15:50:46
5.1 創建object類型對象的三種方式
ES中object類型的對象大致有三種創建方式:直接使用花括號創建、使用function創建以及使用Object.create方法創建。
5.1.1 直接使用花括號創建
使用花括號創建對象時直接將屬性寫到花括號中就可以了,屬性名和屬性值使用冒號(:)分割,不同屬性之間使用逗號(, )分割(注意,最后一個屬性后面沒有逗號),屬性的值可以是直接量,也可以是object類型對象或者function類型對象。我們來看下面的例子。
var obj = { v:6, //直接量屬性 innerObj:{ //object類型對象屬性 v:7 }, logV: function () { //function類型對象屬性 console.log(this.v); } } console.log(obj.v); //6 console.log(obj.innerObj.v); //7 obj.logV (); //6
這個例子中定義了object類型的對象obj,它包括直接量v、object類型對象innerObj以及function類型對象logV三種屬性,其中innerObj對象也是通過花括號來定義的。使用花括號定義完對象之后又分別使用obj對象調用了它的三個屬性。
object對象調用屬性有兩種方法:直接使用點操作符調用;使用方括號調用。因為使用方括號沒有使用點操作符方便,所以一般使用點操作符調用的比較多,不過當屬性名為一個變量時則只能使用方括號來調用,例如下面的例子。
var obj = {a:1, b:2, c:3}; var propName = "c"; console.log(obj[propName]); //3
這個例子中,屬性名保存在propName變量中,這時就只能使用方括號來調用了。
5.1.2 使用function創建
關于使用function創建object實例對象,我們在4.4節中已經講過了,是使用new關鍵字來創建的,而且創建出來的對象還可以使用function的prototype屬性對象中的屬性。具體的內容這里就不再重述了。
5.1.3 使用Object.create方法創建
還有一種創建object類型對象的方式,那就是使用Object.create來創建。Object是ES中內置的一個function類型的對象,create是Object對象的一個屬性方法,其作用是根據傳入的參數創建object類型的對象。create方法的調用語法如下。
Object.create(prototype, [ propertiesObject ])
其中,第一個參數prototype是創建的對象所對應的prototype,相當于使用function創建時function中的prototype屬性對象,創建出來的object對象實例可以直接調用。
第二個參數propertiesObject為屬性描述對象,是可選參數,用于描述所創建對象的自身屬性。屬性描述對象是object類型對象,它里面的屬性名會成為所創建對象的屬性名,屬性值為屬性的描述對象,其中包含屬性的特性(屬性的特性我們后面會詳細講解,這里大家只要知道其中的value就是屬性值就可以了)。我們來看下面的例子。
var obj = Object.create( //prototype { type: "by create" }, //propertiesObject { color: { value: "red", enumerable: true }, size: {
value: "37", enumerable: true } } ); console.log(obj.type); //by create console.log(obj.color); //red console.log(obj.size); //37 console.log(Object.getOwnPropertyNames(obj)); //["color", "size"]
這個例子中,使用Object.create創建了一個obj對象,第一個參數prototype中有一個屬性type,第二個參數propertiesObject有兩個屬性:color和size。對于創建的obj對象來說,這三個屬性都可以使用,但其自身其實只有兩個屬性。雖然obj可以調用prototype中的type屬性,但是并不屬于obj,使用Object.getOwnPropertyNames方法就可以獲取obj自己所擁有的屬性。
另外,需要注意的一點是,使用花括號和function創建的對象都可以調用Object的prototype屬性對象中的屬性。即這兩種方法創建出來的對象首先會擁有公共的prototype,然后使用function創建的對象還可以調用function的prototype中的屬性,而且即使function的prototype為null,創建的對象也可以調用Object的prototype中的屬性。但是,使用Object. create創建對象時,如果第一個參數為null,那么它所創建的對象將不可以調用Object的prototype中的屬性。我們來看下面的例子。
//使用花括號創建對象braceObj var braceObj = {} //使用function創建對象functionObj function F(){} F.prototype = null; var functionObj = new F(); //使用create方法創建對象createObj var createObj = Object.create(null); console.log(braceObj.toString()); //[object Object] console.log(functionObj.toString()); //[object Object] console.log(createObj.toString()); //拋出方法沒找到異常
在這個例子中,toString方法是Object的prototype屬性中的一個方法,如果創建出來的對象可以調用toString方法,就說明可以調用Object的prototype屬性對象中的方法,否則就是不可以調用。從這個例子中可以看出,使用花括號和function創建的對象都可以調用tostring方法,而且即使將function的prototype設置為null,創建出來的對象也可以調用,但使用Object.create創建出來的對象,如果其prototype參數為null就不可以調用了。
多知道點
Object的prototype屬性對象里面都有什么
Object的prototype屬性對象在ES5.1和ES2015中都規定了constructor、toString ( )、toLocaleString ( )、valueOf ( )、hasOwnProperty (V) 、isPrototypeOf (V)和propertyIsEnumerable (V)7個屬性,其中,constructor會默認指向創建對象的function,其他6個是方法,分別介紹如下。
? toString:這是6個方法中最常使用的方法。它可以將對象轉換為字符串,不同類型的對象可能會重寫自己的toString方法。例如,Array的toString方法會將其所包含的元素使用逗號連接起來組成字符串并返回、Date的toString方法會返回Date的時間字符串等,普通object類型對象會返回[object Object]。
? toLocaleString:會使用本地化格式來生成字符串,對于時間日期類型和數字類型的用處較大。
? valueOf:會返回原始值。例如,因為Date類型對象是通過數字來保存的,所以當Date類型對象調用valueOf時就會獲得相應的數字。
? hasOwnProperty:判斷是否包含指定屬性。注意,這里判斷的是對象自身是否包含指定的屬性,不包括創建對象的function對象的prototype中的屬性。
? isPrototypeOf:判斷某個對象是否是另一個對象所對應的prototype對象。
? propertyIsEnumerable:判斷某個屬性是否可以枚舉。關于屬性的枚舉我們到屬性的特性一節再詳細介紹。
例如下面的例子。
function log(msg){ console.log(msg); } var array = [1,3,5]; var date = new Date(); log(array.toString()); //1,3,5 log(date.toString()); //Tue Jun 092015 10:48:10 GMT+0800 log(date.toLocaleString()); //2015/6/9 上午10:48:10 log(date.valueOf()); //1433818090599 從1970年到現在的毫秒數 var Obj = function(){ this.msg = "hello"; this.say = function () { log(msg); } }
var proto = {color: "red"}; Obj.prototype = proto; var obj = new Obj(); log(obj.constructor); //Object() log(obj.hasOwnProperty("msg")); //true log(obj.hasOwnProperty("color")); //false, color在Obj的prototype中, //obj雖然可以調用但是不擁有 log(obj.propertyIsEnumerable("msg")); //true log(obj.isPrototypeOf(proto)); //false log(proto.isPrototypeOf(obj)); //true
通過這個例子,就可以理解Object的prototype屬性對象中7個屬性的用法了。需要注意的是,因為將Obj的prototype屬性賦值為proto對象,所以創建的obj對象在調用constructor屬性時就不會返回Obj對象而是返回Object對象。可以通過對proto對象進行修改來修復這一問題,代碼如下。
var proto = {color: "red"}; proto.constructor = Obj; Obj.prototype = proto; var obj = new Obj(); console.log(obj.constructor); //Obj
這時就可以正確地輸出constructor了。
上面所介紹的是標準中所規定的Object的prototype屬性對象中的7個屬性,但是不同的瀏覽器還會有一些自己的擴展。例如,在Firefox中就擴展到14個屬性:constructor、toSource、toString、toLocaleString、valueOf、watch、unwatch、hasOwnProperty、isPrototypeOf、propertyIsEnumerable、_ _defineGetter_ _、__defineSetter_ _、_ _lookupGetter_ _和_ _lookupSetter_ _。但是,新增的屬性并不是通用屬性,其他瀏覽器中可能并沒有定義,如果使用則很可能造成瀏覽器不兼容的問題,因此應該盡量少使用。如果非要用,那么最好在使用前先判斷瀏覽器是否支持。
- Java程序設計實戰教程
- Visual Basic編程:從基礎到實踐(第2版)
- 認識編程:以Python語言講透編程的本質
- JavaFX Essentials
- 數據結構習題精解(C語言實現+微課視頻)
- C語言程序設計實踐教程
- bbPress Complete
- Mastering Linux Network Administration
- Java EE 8 Application Development
- 運用后端技術處理業務邏輯(藍橋杯軟件大賽培訓教材-Java方向)
- Visual Foxpro 9.0數據庫程序設計教程
- Babylon.js Essentials
- 詳解MATLAB圖形繪制技術
- Learning Hadoop 2
- App Inventor少兒趣味編程動手做