JS中Object的API詳解

derek_skx發表於2019-03-20

Object的api一覽表

Object的使用頻率非常高,熟練掌握其擁有的api,靈活應用,很有必要

ES2019新增API

  • fromEntries
    • 作用:把Object.entries轉換後的二維陣列重新轉換為物件
    • 接受引數:目標陣列
        const obj = {x:3,y:4}
        let entries = Object.entries(obj)    // [[x:3],[y:4]]
        let obj2 = Object.fromEntries(entries)   // {x:3,y:4}
    複製程式碼

API詳解

  • assign

    Object.assign(): 將多個物件合併到目標的屬性合併到目標物件中,相同屬性的值以最後一個合併物件的為準,返回目標物件,不改變被合併物件,可以實現淺克隆

    • 語法: Object(obj,obj1,obj2...)
    • obj: 目標物件,推薦傳{}
    • obj1,obj2...: 被合併的物件,可以傳多個
    • 注意: 相容性不好,PC端IE全不相容,移動端只有少量瀏覽器相容
      let obj = {name: 'derek',age: 18}
      let obj1 ={ name: 'tom', sex: 'F' }
      let result = Object.assign({},obj,obj1,{aa:1})
      result  // => {name:'tom',age:18,sex: 'F',aa:1}
      obj   // => {name: 'derek',age: 18}
      obj1  // => { name: 'tom', sex: 'F' }
    複製程式碼
  • create

    Object.create(): 初始化一個物件,和使用{}基本一樣

    • 語法: Object.create(proto,[propertiesObject])
    • proto:新建立物件的原型物件
    • propertiesObject:可選,要新增到新物件的可列舉(新新增的屬性是其自身的屬性,而不是其原型鏈上的屬性)的屬性。
    • 注意: proto傳null時,建立的物件沒有繼承Object的任何東西(呼叫toString等方法會報錯),如果需要一個非常乾淨且高度可定製的物件當作資料字典的時候或者想節省hasOwnProperty帶來的一丟丟效能損失可以使用,其他時間推薦使用{}
      //傳 null
      let o = Object.create(null,{
        a:{
            writable:true,
            configurable:true,
            value:'1'
        }
      })
      o   // => {}
      let a =o.toString() // => toString is not a function
      // 傳 {}
      let o = Object.create({},{
        a:{
            writable:true,
            configurable:true,
            value:'1'
        }
      })
      o   // => {}
      let a =o.toString() // => [object, Object]
    
    複製程式碼
    • defineProperty

      Object.defineProperty(obj,prop,descriptor):對obj物件上對prop屬性進行定義或修改,其中descriptor為被定義或修改的屬性符。其中對於descriptor屬性符可以設定的值如下顯示

      • value:表示屬性的值,預設為undefined
      • writable:該屬性是否為可寫,如果直接在物件上定義屬性,則預設為true。如果設定為false,則屬性僅為可讀。
      • configurable: 如果為false的話,則不能修改(writabel,configurable,enumerable),如果直接在物件上定義屬性,則預設為true
      • enumerable:是否能夠被列舉,如果直接在物件上定義屬性,則預設為true
      • get:當物件訪問prop屬性的時候,會呼叫這個方法,並返回結果。預設為undefined
      • set:當物件設定該屬性的時候,會呼叫這個方法,預設為undefined 注意:相容性不錯,移動端幾乎全相容,PC端相容IE9以上,IE8也能執行,但是隻能傳dom物件
      var obj = {}, value = null;
      Object.defineProperty(obj, "num", {
          get: function(){
              console.log('執行了 get 操作')
              return value;
          },
          set: function(newValue) {
              console.log('執行了 set 操作')
              value = newValue;
          }
      })
    
      obj.num = 1 // 執行了 set 操作
    
      console.log(obj.num) // 1 執行了 get 操作
    複製程式碼
  • getOwnPropertyDescriptor

    Object.getOwnPropertyDescriptor(obj,prop):查詢prop屬性存是否在物件obj上,在則返回其屬性描述符,如果不存在就返回undefined

    屬性描述符包括:

    • value:表示屬性的值,預設為undefined
    • writable:該屬性是否為可寫,如果直接在物件上定義屬性,則預設為true。如果設定為false,則屬性僅為可讀。
    • configurable: 如果為false的話,則不能修改(writabel,configurable,enumerable),如果直接在物件上定義屬性,則預設為true
    • enumerable:是否能夠被列舉,如果直接在物件上定義屬性,則預設為true
    • get:當物件訪問prop屬性的時候,會呼叫這個方法,並返回結果。預設為undefined
    • set:當物件設定該屬性的時候,會呼叫這個方法,預設為undefined
      let obj = {name: 'derek',age:22,sex:'M'}
      let a = Object.getOwnPrepertyDescriptor(obj,'name')
      let b = Object.getOwnPrepertyDescriptor(obj,'test')
      console.log(a) // => {value:'derek',writable: true,enumerable: true,configurable: true}
      console.log(b) // => undefined
    複製程式碼
  • getOwnPropertyDescriptors

    Object.getOwnPropertyDescriptor(obj):返回一個物件的所有屬性的屬性描述符,沒有屬性返回{}

    屬性描述符包括:

    • value:表示屬性的值,預設為undefined
    • writable:該屬性是否為可寫,如果直接在物件上定義屬性,則預設為true。如果設定為false,則屬性僅為可讀。
    • configurable: 如果為false的話,則不能修改(writabel,configurable,enumerable),如果直接在物件上定義屬性,則預設為true
    • enumerable:是否能夠被列舉,如果直接在物件上定義屬性,則預設為true
    • get:當物件訪問prop屬性的時候,會呼叫這個方法,並返回結果。預設為undefined
    • set:當物件設定該屬性的時候,會呼叫這個方法,預設為undefined
      let obj = {name: 'derek',age:22,sex:'M'}
      let a = Object.getOwnPropertyDescriptors(obj)
      console.log(a) // => {name:{value:'derek',writable: true,enumerable: true,configurable: true},age:{value:22,writable: true,enumerable: true,configurable: true}...}
      let obj = {}
      let b = Object.getOwnPrepertyDescriptor(obj)
      console.log(b) // => {}
    複製程式碼
  • getOwnPropertyNames

    Object.getOwnPropertyNames(obj): 查詢目標物件的所有key值,並返回一個包含所有key值的陣列,和Object.keys()效果一致

      let obj = {name: 'derek',age:22,sex:'M'} 
      let a = Object.getOwnPropertyNames(obj)
      console.log(a) //=> ['name','age','sex']
    複製程式碼
  • keys

    Object.keys(obj): 查詢目標物件的所有key值,並返回一個包含所有key值的陣列,和Object.getOwnPropertyNames()效果一致

      let obj = {name: 'derek',age:22,sex:'M'} 
      let a = Object.keys(obj)
      console.log(a) //=> ['name','age','sex']
    複製程式碼
  • getPrototypeOf

    Object.getPrototypeOf(obj): 該方法返回物件的原型物件,如果沒有的話,則返回null。

      let obj = {name: 'derek',age:22,sex:'M'} 
      let a = Object.getPrototypeOf(obj)
      console.log(a) //=> {}
    複製程式碼
  • is

    Object.is(val1,val2): 是確定兩個值是否是相同的值,

    • 注意:與===相比,其會將-0和+0看成不等,並且對於兩個NaN的比較,Object.is()會看成是相等的,而===會將0、-0、+0看成相等的,兩個NaN看成不等
      Object.is(0,-0) // => false
      Object.is(0,0) // => true
      Object.is(NAN,0/0) // => true
      Object.is(3,3/1) // => true
    複製程式碼
  • preventExtensions

    Object.preventExtensions(obj):讓一個物件永遠不能新增新的屬性,嚴格模式下會報錯

      let obj = {name: 'derek'}
      obj.age = 22 
      console.log(obj.age) // => 22
      Object.preventExtensions(obj)
      obj.sex = 'M'  // 報錯
      obj._proto_.sex = 'M'  //可以在原型物件上新增屬性
      console.log(obj.sex) // => 'M'
    複製程式碼
  • isExtensible

    Object.isExtensible(obj): 判斷一個物件是否可以修改屬性,是放回true,反之返回false

      let obj = {name: 'derek'}
      Object.isExtensible(obj) //=> true
    複製程式碼
  • seal

    Object.seal(obj):對一個物件進行密封,並返回被密封的物件,這些物件都是不能夠新增屬性,不能刪除已有屬性,以及不能夠修改已有屬性的可列舉型、可配置型、可寫性

      let obj = {name: 'derek'}
      Object.seal(obj)
      obj.name = 'tom' // 可以修改原有屬性對應的值
      console.log(obj) // => {name:'tom'}  
      obj.test = 'test' // 不能給物件新增新屬性
      console.log(obj)  // => {name: 'tom'}
      delete obj.name   // 不能刪除物件的屬性
      console.log(obj)  // => {name: 'tom'}
    複製程式碼
  • isSealed

    Object.isSealed(obj): 判斷一個物件是否被密封,是放回true,反之返回false

      let obj = {name: 'derek'}
      Object.isSealed(obj) //=> false
      Object.freeze(obj)
      Object.isSealed(obj) //=> true
    複製程式碼
  • freeze

    Object.freeze(obj):淺凍結一個物件,使其不能做任何修改,深層級的還是可以修改

      let obj = {name: 'derek',child:{age:18}}
      Object.freeze(obj)
      obj.name = 'tom' // 不能修改原有屬性對應的值
      console.log(obj) // => {name:'derek'}  
      obj.test = 'test' // 不能給物件新增新屬性
      console.log(obj)  // => {name: 'derek'}
      delete obj.name   // 不能刪除物件的屬性
      console.log(obj)  // => {name: 'derek'}
    
      obj.child.age=22 // 可以對深層級的進行修改
      console.log(obj.child) // => {age:22}
    複製程式碼

    如果要實現深度凍結,可以通過遞迴來實現

      Object.prototype.deepFreeze = Object.prototype.deepFreeze || function (o){
        let prop, propKey
        Object.freeze(o) // 首先凍結第一層物件
        for (propKey in o){
            prop = o[propKey];
            if(!o.hasOwnProperty(propKey) || !(typeof prop === "object") || Object.isFrozen(prop)){
                continue;
            }
            deepFreeze(prop); // 遞迴
        }
      }
    複製程式碼
  • isFrozen

    Object.isFrozen(obj): 判斷一個物件是否被凍結,是放回true,反之返回false

      let obj = {name: 'derek'}
      Object.isFrozen(obj) //=> false
      Object.freeze(obj)
      Object.isFrozen(obj) //=> true
    複製程式碼
  • getOwnPropertySymbols

    Object.getOwnPropertySymbols(obj): 返回一個物件中所有以Symbol型別為key的的陣列

      let obj = {name: 'derek'}
      let a =Object.getOwnPropertySymbols(obj)
      console.log(a) // => []
      let sys = Symbol()
      obj[sys] = 'test'
      let b =Object.getOwnPropertySymbols(obj)
      console.log(b) // => [Symbol()]
    複製程式碼
  • entries

    Object.entries(obj): 將物件中的所有key:value轉為[key,value]格式,返回包含所有健值對的二維陣列

      let obj = {name: 'derek',age:18}
      let result = Object.entries(obj) 
      console.log(result) // => [['name','derek'],['age',18]]
    複製程式碼
  • values

    Object.values(obj): 返回一個物件的所有value值的陣列集合

      let obj = {name: 'derek',age:18}
      let result = Object.values(obj) 
      console.log(result) // => ['derek',18]
    ``複製程式碼

相關文章