博客 / 詳情

返回

【js】Object上的一些方法

Object上的一些方法

  1. assign
  2. create
  3. defineProperties
  4. defineProperty
  5. keys
  6. values
  7. entries
  8. freeze
  9. isFrozen
  10. seal
  11. isSealed
  12. getPrototypeOf
  13. setPrototypeOf
  14. is
  15. isExtensible
  16. preventExtensions
  17. getOwnPropertyDescriptor
  18. getOwnPropertyDescriptors
  19. getOwnPropertySymbols
  20. getOwnPropertyNames

1.Object.assign(target,source)

可枚舉屬性的值從一個或對個對象分配到目標對象,返回目標對象

const target = { a: 1, b: 2 }
const source = { b: { b1: 3 }, c: 4 }
const result = Object.assign(target, source)
console.log(result, target);
target.b.b1 = 10

image.png

  • 可以看出assign是一種淺拷貝,沒有開闢新的存儲空間去存拷貝來的值,直接的引用

2.Object.create(proto,propertiesObject)

  1. 創建一個空對象
  2. 第一個參數作為該對象的原型
  3. 第二個參數為該對象的默認屬性

    function School(name) {
     this.name = name
    }
    let obj = Object.create(School.prototype, {
     p: {
         value: 4,
         enumerable: false,
         writable: false,
         configurable: false
     },
     length: {
         value: 0
     }
    })
    obj.q = 5
    obj.p = 5 //writable為false,不可修改
    delete obj.p //configurable為false,刪除失敗
    for (let i in obj) {
     console.log(i);//enumerable為false,p不被枚舉
    }
    console.log(obj);

    image.png

    • 默認的屬性可以配置屬性,枚舉,可寫,可配置

3.Object.defindeProperty(obj,prop,descriptor)與Object.defineProperties(obj,props)

  1. Object.defindeProperty在一個對象上定義或修改一個屬性,返回該對象

    • descriptor

      • writable 可寫
      • enumerable 可枚舉
      • configurable 可刪除
      • value 值
      • get 讀值
      • set 設置值
    let o = {
     a: {
         name: "張三",
         age: 18,
     }
    }
    var val = null
    Object.defineProperty(o.a, "rank", {
     configurable: false,
     enumerable: true,
     get() {
         console.log("獲取張三排名");
         return val
     },
     set(newval) {
         console.log("新值:" + newval);
         val = newval
     }
    })
    o.a.rank = 1
    console.log(o.a.rank);
    console.log(o);

    image.png

    • get setvalue writable不能同時使用
    • 在添加rank值時set會監聽到,可以賦值給一個中間變量或者該對象上的一個屬性,get會在rank時執行
    • 點擊rank的三個點也會監聽到讀的操作

    image.png

  2. Object.defineProperties(obj,props)
    defineProperty有三個參數,但是隻針對一個屬性
    defineProperties的第二個參數不是一個字符串,是一個對象
    它將defineProperty的第三個參數融合到第二個參數裏
    可以去配置多個屬性

    let o = {
     a: {
         name: "張三",
         age: 18,
     }
    }
    var val = null
    let a = Object.defineProperties(o.a, {
     "rank": {
         value: 1,
     },
     "grade": {
         get() {
             console.log("讀:" + val);
             return val
         },
         set(newval) {
             console.log("改" + newval);
             val = newval
         }
     }
    }
    )
    o.a.grade = 9
    console.log(o.a.rank, o.a.grade);
    console.log(a);

    image.png

    • 屬性的相關配置默認均為false

4.Object.getOwnPropertyDescriptor(obj,prop)和Object.getOwnPropertyDescriptors(obj)

  • 獲取指定對象自身屬性的描述符
  • 一個是獲取單個,一個獲取全部

    const o = {}
    let val = 0
    Object.defineProperties(o, {
      a: {
          value: 1,
          enumerable: true,
          configurable: false,
      },
      b: {
          configurable: false,
          enumerable: false,
          get() {
              return val
          },
          set(newval) {
              val = newval
          }
      }
    })
    let d1 = Object.getOwnPropertyDescriptor(o, "a")
    let d2 = Object.getOwnPropertyDescriptors(o)
    console.log(d1, d2);

    image.png

    普通的追加對象屬性,也會返回相關描述
    不過與defineProperty的默認值false正好相反

5.Object.keys(obj) Object.values(obj) Object.entries(obj)

  • keys:返回給定對象可枚舉屬性值組成的數組
  • values:返回給定對象可枚舉屬性名組成的數組
  • entries:返回給定對象可枚舉鍵值對組成的數組

    const o = {
      a: 1,
      b: 2,
      fn() {
      }
    }
    for (const k of Object.keys(o)) {
      console.log(k);//a b fn
    }
    for (const v of Object.values(o)) {
      console.log(v);//1 2 fu(){}
    }
    for (const e of Object.entries(o)) {
      console.log(e);//["a",1] ["b",2] ["fn",fn()]
    }
    數組原型上的keys()方法 返回的是Number類型,Object上返回的是字符串

6.freeze(obj) isFrozen()、seal(obj) isSealed()、preventExtensions() isExtensible

  • freeze凍結一個對象,不可修改,不可加屬性,不可刪屬性,其原型也不能修改
  • seal封閉一個對象,可修改已有屬性,不可加屬性,不可刪除屬性,原型不可修改
  • preventExtensions不可擴展, 可刪除,可修改,不可加屬性,原型不可修改

    const o1 = { a: 1, b: 2, fn() { } }
    Object.freeze(o1)
    console.log(Object.isFrozen(o1));//true
    o1.a = 2
    console.log(o1.a);// 1
    
    const o2 = { a: 1, b: 2, fn() { } }
    Object.seal(o2)
    console.log(Object.isSealed(o2));//true
    o2.a = 2
    console.log(o2.a);//2
    
    const o3 = { a: 1, b: 2, fn() { } }
    Object.preventExtensions(o3)
    console.log(Object.isExtensible(o3));//false
    o3.a = 2
    console.log(delete o3.b);//true
    console.log(o3.a);//2
    freeze與seal都不可擴展且不可刪除,isExtensible的值也為false

7.Object.setPrototypeOf(obj,prototype) Object.getPrototypeOf(obj)

  • 設置對象的原型與獲取對象的原型

    const obj = {
      name: "obj",
      getName() {
          console.log(this.name)
      }
    }
    let o = {
      name: "o"
    }
    Object.setPrototypeOf(o, obj)
    Object.getPrototypeOf(o).getName()//obj
    o.getName()//o
    不建議使用這種方式以及__proto__去修改原型
    使用Object.create()來創建一個指定原型的新對象

8.Object.is(value1,value2)

  • 判斷兩個值是否為同一個值
const o1 = {
    a: 1
}
const o2 = { b: { c: 2 } }
const o3 = { b: { c: 2 } }
Object.assign(o1, o2)
console.log(Object.is(o1.b, o2.b));//true
console.log(Object.is(o1.b, o3.b));//false
引用的地址不同會檢測出是不同的值
對於原始類型,只要值相同即可
可以看出Object.assign()是淺拷貝,對用引用類型並沒有開闢新的內存空間去存儲,只是複製了棧指針的指向

9.Object.getOwnPropertyNames(obj)和Object.getOwnPropertySymbols(obj)

  • getOWnPropertyNames返回指定對象的屬性名組成的數組,包括不可枚舉的屬性,但不包括Symbol值的屬性名
  • getOwnPropertySymbols返回指定對象所有以Symbol為屬性名的數組

    let f = Symbol("foo")
    const o = {
      [f]: 1,
      "a": 2,
      b: 3
    }
    const n = Object.getOwnPropertyNames(o)
    const s = Object.getOwnPropertySymbols(o)
    console.log(n, s);//["a","b"] [Symbol(foo)]

原型上的方法

1.hasOwnProperty
2.isPrototypeOf
3.propertyIsEnumerable
4.toLocalString
5.toString
6.ValueOf
7.__defineGetter__(已廢棄)
8.__defineSetter__(已廢棄)
9.__lookupSetter__(已廢棄)
10.__lookupSetter__(已廢棄)
11.__proto__(屬性 已廢棄)
12.toSource()(非標準)

1.Object.prototype.hasOwnProperty(prop)

  • 檢測指定屬性是否有某個屬性,可以檢測到Symbol類型

    const a = [1]
    console.log(a.hasOwnProperty(0));//true
    let s = Symbol("foo")
    const o = {
      [s]: "a",
    }
    console.log(o.hasOwnProperty(s));//true

2.Object.prototype.isPrototypeOf(obj)

  • 檢測一個對象是否在另一個對象的原型鏈

    function School(name) {
      this.name = name
    }
    School.prototype = {
      constructor: School,
      getName() {
          console.log(this.name);
      }
    }
    function Student(name) {
      School.call(this, name)
    }
    Student.prototype = Object.create(School.prototype)
    Student.prototype.constructor = Student
    const std1 = new Student("張三")
    std1.getName() //張三
    console.log(School.prototype.isPrototypeOf(std1));//true
    上面用組合寄生的方式實現的繼承
    可以檢測出父類的原型子類實例的原型鏈上

3.Object.prototype.peopertyIsEnumerable(prop)

  • 檢測指定對象的某屬性是否可枚舉

    let s1 = Symbol("s1")
    let s2 = Symbol("s2")
    const o = {
      [s1]: 0,
    }
    Object.defineProperties(o, {
      [s2]: {
          value: 1,
          enumerable: true
      },
      p: {
          value: 3,
      }
    })
    console.log(o.propertyIsEnumerable(s1));//true
    console.log(o.propertyIsEnumerable(s2));//true
    console.log(o.propertyIsEnumerable("p"));//false

4.toLocalString() toString() valueOf()

  • toLocalString返回的是本地環境字符串,適合處理時間類型
  • toString返回唯一字符串,不會因為環境的改變而變化
  • valueOf返回對象的原始值

統一方法

function transform(o) {
    console.log(Object.prototype.toLocaleString.call(o));
    console.log(Object.prototype.toString.call(o));
    console.log(Object.prototype.valueOf.call(o));
}

基本數據類型

transform(1000)
//"1000" "[object Number]" {1000}
transform(true)
//"true" "[object Boolean]" {true}
transform(Symbol("smb"))
//"Symbol('smb')" "[object Symbol]" {Symbol(smb)}
transform(1000n)
//"1000" "[object BigInt]" {1000n}
transform("str")
//"str" "[object String]" {"str"}

引用數據類型

transform([0, 1])
//"0,1" "[object Array]" [0,1]
transform({ a: 0, b: 1 })
//"[object Object]" "[object Object]" {a:0,b:1}
transform(new Date())
//"標準時間" "[object Date]" "標準時間"
transform(function () { })
//"function () { }" "[object Function]" f () {}
transform(new Error("e"))
// "Error:e" "[object Error]" Error: e
  • 可以看出toLocalString返回其內容的字符串
  • toString返回值唯一 都是方括號object + 數據類型的字符串
  • valueOf基本類型會返回一個對象 引用類型返回其本身
user avatar lanlanjintianhenhappy 頭像 ziyeliufeng 頭像 sunhengzhe 頭像 mapvthree 頭像
4 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.