Object上的靜態方法

戎馬發表於2019-02-16

內建提供了一個物件為 Object ,也被稱之為是建構函式,用來建立物件用的。在 javascript 函式也是物件,是一種可被執行的物件,所以稱Object為物件也是可以的。掛在函式上的方法,稱之為靜態方法。

Object.defineProperty()

如果對這個方法不瞭解,必須先看,下面的某些方法要定義不可列舉的屬性時會用到。

移步閱讀:https://segmentfault.com/a/1190000007434923

Object.getOwnPropertyDescriptor()

方法返回指定物件上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該物件的屬性,不需要從原型鏈上進行查詢的屬性)

屬性描述符是一個物件,記錄了此屬性,是否可被列舉、是否可被刪除、是否可被改寫、屬性的值。

let obj = {a:1,b:2};

console.log(Object.getOwnPropertyDescriptor(obj,`a`));

返回值是一個物件:

{
    configurable: true
    enumerable: true
    value: 1
    writable: true
}

一般物件定義的屬性,不使用 Object.defineProperty() 定義的,都是可被列舉、可被刪除、可被改寫。

Object.getOwnPropertyNames()

方法返回一個由指定物件的所有自身屬性的屬性名(包括不可列舉屬性)組成的陣列。

let obj = {
    a:1,
    b:2
}
console.log(Object.getOwnPropertyNames(obj)); //[`a`,`b`]


Object.defineProperty(obj,`c`,{
    enumerable: false
})

console.log(Object.getOwnPropertyNames(obj)); //[`a`,`b`,`c`]

Object.assign()

這個方法被經常用到,作用是將一個或多個物件可列舉的屬性合併到目標物件上,返回為目標物件。

用法:

let target = {a:1};

let t = Object.assign(target,{b:1},{c:1})

console.log(target); // {a:1,b:1,c:1}
console.log(t); // {a:1,b:1,c:1}
console.log(target === t); // true

通過以上測試會發現,將多個物件的屬性都合併到了物件 target 上,並且返回的依然是物件 target
要注意,這種方式為淺拷貝(淺複製),遇到值為物件型別時,會引用相同的物件。

let target = {a:1};
let source = {b:1,users:[`seven`]

Object.assign(target,source)

target.users.push(`job`); 

console.log(target.users); // [`seven`,`job`]
console.log(source.users); // [`seven`,`job`]

以上的屬性 users 對應的值為陣列,陣列是引用型別的值,並沒有複製一份給到 target,所以物件 targetsource 使用的是同一個物件。改變後會互相影響,如果要完全的脫離關係,可以選擇深複製,利用 jQueryextend 函式。

此函式常用的應用場景是覆蓋函式定義的物件預設值,例如要封裝一個 Ajax ,要傳遞很多個引數,某些引數是可選的,採用傳遞一個物件的方式更利於擴充套件:

function Ajax(options){
    let defautls = {
        method:`get`,
        data:{},
        success(){},
        error(){}
    }
    Object.assign(defautls,options)
}
Ajax({
    method:`post`
})

物件屬性是可選的,預先定義好預設值,當呼叫函式傳遞的屬性覆蓋掉預設設定的屬性。

Object.create()

此方法用基於傳入的引數物件作為原型來建立一個新物件。只能接受物件或者null作為引數。檢視新物件的 proto 的值,為傳入的引數物件。

let obj = {
    a:1,
    b:2
}
let newObject = Object.create(obj);

console.log(newObject.__proto__ === obj); // true

以上就是把 obj 物件作為新建立物件的原型。

也可以傳入 null,意思是建立一個沒有任何原型的物件,這樣建立物件的方式更加高效。

應用場景為原型繼承上,例如一個函式的原型需要繼承另一個原型,就可以就可以基於一個原型物件建立一個新的物件,把新的物件賦值給另一個原型即可。

// 父類
function Person(){}
Person.prototype.say = function(){}

子類
function Coder(){}
// 需要繼承父類Peroson原型物件
Coder.prototype = Object.create(Person.prototype.)

Object.is

判斷值是否相同,連一個奇葩的自身和自身不相等的 NaN 都可以判斷為相同。

console.log(Object.is(1,1)); // true
console.log(Object.is(NaN,NaN)); //true

Object.getPrototypeOf()

返回指定物件的原型物件,(內部[[Prototype]]屬性的值)。[[Prototype]] 為內部使用的,我們一般使用 proto 這個瀏覽器提供的屬性來獲取物件的原型,但在 ES5 規範中 proto 並不是標準的屬性,是瀏覽器為了方便開發者檢視物件的原型提供的,因為這個屬性使用起來方便,現在大多數瀏覽器都提供。如果要用規範方法獲取原型物件,建議使用 Object.getPrototypeOf

console.log(Object.getPrototypeOf({}) === Object.prototype); // true

let obj = {a:1};
let newObj = Object.create(obj); // 基於obj為原型建立新的物件

console.log(Object.getPrototypeOf(newObj) === obj); // true
console.log(newObj.__proto__ === Object.getPrototypeOf(newObj)); // true

Object.setPrototypeOf()

這個方法設定一個指定的物件的原型 ( 即, 內部[[Prototype]]屬性)到另一個物件或 null。

let obj = {
    a:1,
    b:2
}

console.log(Object.getPrototypeOf(obj) === Object.prototype)

let newProto = {
    c:1
}

Object.setPrototypeOf(obj,newProto); // 把obj物件的原型設定為物件newProto

console.log(Object.getPrototypeOf(obj) === newProto); // true

Object.keys

方法會返回一個由一個給定物件的自身可列舉屬性組成的陣列,陣列中屬性名的排列順序和使用 for…in 迴圈遍歷該物件時返回的順序一致 。

要注意,Object.keys 方法不能遍歷出不可列舉的屬性,要遍歷出不可列舉屬性,可使用 Object.getOwnPropertyNames

let obj = {
    a:1,
    b:2
}
Object.defineProperty(obj,`c`,{
    enumerable: false
})

console.log(Object.keys(obj)); //[`a`,`b`]

Object.values

返回一個給定物件自身的所有可列舉屬性值的陣列。與使用 for…in 迴圈順序保持一致,但 Object.values 不遍歷原型鏈。
把物件的 value 值存放在一個陣列中。

let obj = {
    a:1,
    b:2
}
console.log(Object.values(obj)); //[1,2]

Object.entries

返回一個給定物件自身可列舉屬性的鍵值對陣列,與使用 for…in 迴圈順序保持一致,但 Object.entries 不遍歷原型鏈。

let obj = {a:1,b:2};
let keyValueArr = Object.entries(obj);
console.log(keyValueArr); // 列印:[["a", 1],["b", 2]]

把物件的 keyvalue 存放在同一個陣列中,第一項為 key ,第二項為 value

這個方法常常配合 for…of 語法使用來遍歷物件,

let obj = {a:1,b:2};
for(let [key,value] of Object.entries(obj)){
    console.log(key,value); // `a`,1;`b`,2
}

[key,value] 形式為解構賦值,右側 Object.entries(obj) 返回的是一個二維陣列 [[“a”, 1],[“b”, 2]],這樣每次拿到陣列中的一項 [“a”,1],利用解構賦值的形式,將陣列第一項賦值給 key,第二項賦值給 value

以上常用的方法:

  • 合併或複製物件使用Object.assgin;
  • 遍歷物件使用 Object.keys
  • 建立物件使用 Object.create

以上如有偏差歡迎指正學習,謝謝。

相關文章