官术网_书友最值得收藏!

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_ _。但是,新增的屬性并不是通用屬性,其他瀏覽器中可能并沒有定義,如果使用則很可能造成瀏覽器不兼容的問題,因此應該盡量少使用。如果非要用,那么最好在使用前先判斷瀏覽器是否支持。

主站蜘蛛池模板: 五台县| 文安县| 九江县| 年辖:市辖区| 卢龙县| 墨脱县| 南丰县| 静海县| 金阳县| 婺源县| 定结县| 康平县| 旺苍县| 秦安县| 巴彦县| 广元市| 房山区| 大连市| 大余县| 施甸县| 通州区| 司法| 根河市| 田林县| 焉耆| 武宁县| 抚松县| 盖州市| 汉川市| 盐城市| 荃湾区| 青川县| 金湖县| 康马县| 林州市| 柏乡县| 陕西省| 昭通市| 将乐县| 阿坝| 邵阳市|