內建提供了一個物件為 Object ,也被稱之為是建構函式,用來建立物件用的。在 javascript 函式也是物件,是一種可被執行的物件,所以稱Object為物件也是可以的。掛在函式上的方法,稱之為靜態方法。
Object.defineProperty()
如果對這個方法不瞭解,必須先看,下面的某些方法要定義不可列舉的屬性時會用到。
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,所以物件 target 和 source 使用的是同一個物件。改變後會互相影響,如果要完全的脫離關係,可以選擇深複製,利用 jQuery 的 extend 函式。
此函式常用的應用場景是覆蓋函式定義的物件預設值,例如要封裝一個 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]]
把物件的 key 和 value 存放在同一個陣列中,第一項為 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
以上如有偏差歡迎指正學習,謝謝。