tip:
本文僅作為查找和基本使用的展示,需要深入了解這些方法的使用請參考:Object - JavaScript | MDN (mozilla.org)
可以通過目錄快速鎖定需要查找的方法和查看它的使用
目錄
tip:
新建一個對象
?實例屬性
實例方法
hasOwnProperty(key)
isPrototypeOf(obj)
propertyIsEnumerable(prop)
toLocaleString()
toString()
?valueOf()
靜態方法
?Object.assign(target, ...sources)
?Object.create(proto) ?
Object.defineProperties(obj, props)
Object.defineProperty(obj, prop, descriptor)
Object.entries(obj)
Object.fromEntries(iterable)
Object.getOwnPropertyDescriptor(obj, prop)
Object.getOwnPropertyDescriptors(obj)
?Object.getOwnPropertyNames(obj)
Object.getOwnPropertySymbols(obj)
Object.getPrototypeOf(obj)
Object.groupBy(item, callback)---2024新增
Object.hasOwn(obj, prop)
Object.is(value1, value2)
Object.preventExtensions(obj),Object.isExtensible(obj)
Object.freeze(obj)
Object.isFrozen(obj)
?Object.seal(obj),Object.isSealed(obj)
?Object.keys(obj)
?Object.values(obj)
?Object.setPrototypeOf(obj, prototype)
方法總覽
新建一個對象
// 新建一個對象const obj = {//通過{}name:'Tom',age:18
}
const obj1 = new Object({//通過構造函數name:'Tom',age:18
})
const obj2 = Object.create({ //通過靜態方法name:'Tom',age:18
})//注意這里的參數不是生成對象的結果,參數會作為obj2的原型,obj2本身是一個新的空對象console.log(obj,obj1,obj2);console.log("\n----------分割線----------\n");
?實例屬性
// 實例屬性// constructor 對象的實例屬性
// 除了 null 原型對象之外,任何對象都會在其 [[Prototype]] 上有一個 constructor 屬性。
// Object 實例的 constructor 數據屬性返回一個引用,指向創建該實例對象的構造函數(函數本身而不是字符串)
// 可以用來判斷對象類型
const arr = [];
const number = 1;
console.log(obj.constructor === Object);//true
console.log(arr.constructor === Array);//true
console.log(number.constructor === Number);//trueconsole.log("\n----------分割線----------\n");
實例方法
hasOwnProperty(key)
方法會返回一個布爾值,如果自身有這個key屬性(不包括原型中繼承的屬性),則返回 true,否則返回 false。
// hasOwnProperty(key) 方法會返回一個布爾值,如果自身有這個key屬性(不包括原型中繼承的屬性),則返回 true,否則返回 false。
console.log({name:'Tom'}.hasOwnProperty('name'));//true
console.log({name:undefined}.hasOwnProperty('name'));//true,這里的name值雖然是undefined,但是屬性存在
console.log(['Tom'].hasOwnProperty('0'));//true,數組也是對象,可以將索引看成key
console.log([].hasOwnProperty('length'));//true,數組固有的屬性lengthconsole.log("\n----------分割線----------\n");
isPrototypeOf(obj)
返回布爾值 判斷當前對象是否在obj的原型鏈中,(對象---原型鏈)和object instanceof AFunction不同,這是比較兩個對象的原型鏈 ,(原型鏈---原型鏈)
// isPrototypeOf(obj) 返回布爾值 判斷當前對象是否在obj的原型鏈中,(對象---原型鏈)
// 和object instanceof AFunction不同,這是比較兩個對象的原型鏈 ,(原型鏈---原型鏈)
console.log(Object.prototype.isPrototypeOf({}));//true,Object出現在{}的原型鏈中
console.log(Array.prototype.isPrototypeOf([]));//true,Array出現在[]的原型鏈中console.log("\n----------分割線----------\n");
propertyIsEnumerable(prop)
方法返回一個布爾值,表示prop是否是對象的可枚舉自有屬性(遍歷時是否會被訪問,能否出現在for in循環中)
大多數內置屬性默認情況下是不可枚舉的,而用戶創建的對象屬性通常是可枚舉的,除非明確指定為不可枚舉。
// propertyIsEnumerable(prop) 方法返回一個布爾值,表示prop是否是對象的可枚舉自有屬性(遍歷時是否會被訪問,能否出現在for in循環中)
// 大多數內置屬性默認情況下是不可枚舉的,而用戶創建的對象屬性通常是可枚舉的,除非明確指定為不可枚舉。
console.log({name:'Tom'}.propertyIsEnumerable('name'));//true,name屬性可以遍歷
console.log(['0'].propertyIsEnumerable('0'));//true,索引屬性可以遍歷
console.log(['0'].propertyIsEnumerable('length'));//false,length屬性不可遍歷console.log("\n----------分割線----------\n");
toLocaleString()
?返回一個字符串,返回調用toString()的結果(return this.toString())
// toLocaleString() 返回一個字符串,返回調用toString()的結果(return this.toString())
console.log({name:'Tom'}.toLocaleString());//"[object Object]"console.log("\n----------分割線----------\n");
toString()
返回一個表示該對象的字符串。打印實例時默認調用該方法
// toString() 返回一個表示該對象的字符串。打印實例時默認調用該方法
console.log({name:'Tom'}.toString());//"[object Object]"console.log("\n----------分割線----------\n");
?valueOf()
返回指定對象的原始值。值傳遞時可以使用valueOf將值提取出來
// valueOf() 返回指定對象的原始值。值傳遞時可以使用valueOf將值提取出來
const obj3 = {name:'Tom'}
let newObj = obj3.valueOf();// 值傳遞,此時newObj和obj3并不是指向同一個內存
console.log(obj3.valueOf());// {name:'Tom'},返回對象本身的值
console.log(obj3.valueOf() === obj3);//trueconsole.log("\n----------分割線----------\n");
靜態方法
?Object.assign(target, ...sources)
將source中所有可以遍歷的鍵值對,放入target中,返回target;target和source中相同的key,source中的值會覆蓋target中的值,target 待修改的對象 ,source 多個對象
// Object.assign(target, ...sources) 將source中所有可以遍歷的鍵值對,放入target中,返回target
// target和source中相同的key,source中的值會覆蓋target中的值
// target 待修改的對象 ,source 多個對象
console.log(Object.assign({},{name:'tom'},{age:'10'}));// {name:'tom',age:'10'}
console.log(Object.assign({},[1,2,3,4]));// {0:1,1:2,2:3,3:4}
console.log(Object.assign({},[1,2,3,4],'sss'));// { '0': 's', '1': 's', '2': 's', '3': 4 },字符串會被拆分成單個字符作為對象,后面的屬性值會覆蓋前面的console.log("\n----------分割線----------\n");
?Object.create(proto) ?
靜態方法以proto作為原型,創建一個新對象。
// Object.create(proto) 靜態方法以proto作為原型,創建一個新對象。
const obj4 = Object.create([]);//以[]作為原型,創建一個新對象,數組對象
console.log(obj4);//Array {}console.log("\n----------分割線----------\n");
Object.defineProperties(obj, props)
靜態方法直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,并返回這個對象。
obj:在其上定義或修改屬性的對象; props: 一個對象,其中每個鍵表示要定義或修改的屬性的名稱,每個值是描述該屬性的對象(是否只讀,是否可枚舉遍歷,)
// Object.defineProperties(obj, props) 靜態方法直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,并返回這個對象。
// obj:在其上定義或修改屬性的對象; props: 一個對象,其中每個鍵表示要定義或修改的屬性的名稱,每個值是描述該屬性的對象(是否只讀,是否可枚舉遍歷,)
console.log(Object.defineProperties({name:'Tom'
},
{//屬性描述對象name:{value:'Jerry',writable:true //可讀寫}
}));//{name:'Jerry'}console.log("\n----------分割線----------\n");
Object.defineProperty(obj, prop, descriptor)
靜態方法會直接在obj上定義一個新屬性prop,或修改其現有屬性prop,并返回此對象。
obj:待修改的對象 prop:obj對象待修改的屬性名 descriptor:屬性描述對象
// Object.defineProperty(obj, prop, descriptor) 靜態方法會直接在obj上定義一個新屬性prop,或修改其現有屬性prop,并返回此對象。
// obj:待修改的對象 prop:obj對象待修改的屬性名 descriptor:屬性描述對象
console.log(Object.defineProperty({name:'Tom'},'name',{value:'Jerry'}));//{name:'Jerry'}console.log("\n----------分割線----------\n");
Object.entries(obj)
返回一個obj自身可枚舉(可遍歷)屬性的鍵值對數組(元組),
其排列與使用 for...in 循環遍歷該對象時返回的順序一致(區別在于 for...in 循環還會枚舉其原型鏈中的屬性)。
// Object.entries(obj) 返回一個obj自身可枚舉(可遍歷)屬性的鍵值對數組(元組),
// 其排列與使用 for...in 循環遍歷該對象時返回的順序一致(區別在于 for...in 循環還會枚舉其原型鏈中的屬性)。
console.log(Object.entries({name:'Tom',age:18}));//[["name","Tom"],["age",18]]console.log("\n----------分割線----------\n");
Object.fromEntries(iterable)
將鍵值對列表(iterable)轉換為一個對象。
iterable:一個包含對象列表的可迭代對象,例如 Array 或者 Map。
每個對象都要有兩個屬性,0:表示屬性鍵的字符串或者 Symbol。1:屬性值。通常,該對象被實現為二元數組,第一個元素是屬性鍵,第二個元素是屬性值。
// Object.fromEntries(iterable) 將鍵值對列表(iterable)轉換為一個對象。
// iterable:一個包含對象列表的可迭代對象,例如 Array 或者 Map。
// 每個對象都要有兩個屬性,0:表示屬性鍵的字符串或者 Symbol。1:屬性值。通常,該對象被實現為二元數組,第一個元素是屬性鍵,第二個元素是屬性值。console.log(Object.fromEntries([['name','Tom'],['age',18]]));//{name:'Tom',age:18}console.log("\n----------分割線----------\n");
Object.getOwnPropertyDescriptor(obj, prop)
返回obj上一個自有屬性prop對應的屬性描述對象,如果obj上沒有prop屬性返回undefined。
obj:待查詢的對象 prop:string或者symbol 待查詢的屬性名
// Object.getOwnPropertyDescriptor(obj, prop) 返回obj上一個自有屬性prop對應的屬性描述對象,如果obj上沒有prop屬性返回undefined。
// obj:待查詢的對象 prop:string或者symbol 待查詢的屬性名console.log(Object.getOwnPropertyDescriptor({name:'Tom'},'name'));
//{value:'Tom',writable:true,enumerable:true,configurable:true}console.log("\n----------分割線----------\n");
Object.getOwnPropertyDescriptors(obj)
返回obj的所有自有屬性屬性描述對象。obj:待查詢的對象,類似于Object.getOwnPropertyDescriptor
// Object.getOwnPropertyDescriptors(obj) 返回obj的所有自有屬性屬性描述對象。obj:待查詢的對象,類似于Object.getOwnPropertyDescriptorconsole.log(Object.getOwnPropertyDescriptors({name:'Tom',age:18}));//{name:{...},age:{...}}console.log("\n----------分割線----------\n");
?Object.getOwnPropertyNames(obj)
返回obj對象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol屬性)組成的數組。
// Object.getOwnPropertyNames(obj) 返回obj對象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol屬性)組成的數組。console.log(Object.getOwnPropertyNames({name:'Tom',age:18}));//['name','age']console.log("\n----------分割線----------\n");
Object.getOwnPropertySymbols(obj)
返回obj對象自身的所有 Symbol 屬性的數組。
// Object.getOwnPropertySymbols(obj) 返回obj對象自身的所有 Symbol 屬性的數組。console.log(Object.getOwnPropertySymbols({[Symbol('name')]:1,[Symbol('age')]:2, name:'Tom',age:18}));//[Symbol(name),Symbol(age)]console.log("\n----------分割線----------\n");
Object.getPrototypeOf(obj)
返回obj對象的原型對象。即內部 [[Prototype]] 屬性的值
// Object.getPrototypeOf(obj) 返回obj對象的原型對象。即內部 [[Prototype]] 屬性的值console.log(Object.getPrototypeOf({}));//Object
console.log(Object.getPrototypeOf([]));//Arrayconsole.log("\n----------分割線----------\n");
Object.groupBy(item, callback)---2024新增
返回一個對象,對象內根據callback的返回值,將item進行分類。?item:待分類的可迭代對象 ?callback:回調函數,返回值作為分類的依據
const items = [{ name: "蘆筍", type: "蔬菜", quantity: 5 },{ name: "香蕉", type: "水果", quantity: 0 },{ name: "山羊", type: "肉", quantity: 23 },{ name: "櫻桃", type: "水果", quantity: 5 },{ name: "魚", type: "肉", quantity: 22 },
];
const result = Object.groupBy(items, ({type}) => type);//此方法目前只在瀏覽器支持
console.log(result);//{蔬菜:{...},水果:{...},肉:{...}}
Object.hasOwn(obj, prop)
返回布爾值,檢查obj對象自身是否具有指定的屬性prop。Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()。
// Object.hasOwn(obj, prop) 返回布爾值,檢查obj對象自身是否具有指定的屬性prop。Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()。console.log(Object.hasOwn({name:'Tom'},'name'));//trueconsole.log("\n----------分割線----------\n");
Object.is(value1, value2)
返回布爾值,判斷兩個值是否為同一個值。
Object.is() 與 == 運算符并不等價, 也不等價于 === 運算符,相比于 == Object.is()轉換類型比較,相比于 === Object.is()不會忽略 +0 和 -0,也不會把 NaN 等于 NaN。
// Object.is(value1, value2) 返回布爾值,判斷兩個值是否為同一個值。
// Object.is() 與 == 運算符并不等價, 也不等價于 === 運算符,相比于 == Object.is()轉換類型比較,相比于 === Object.is()不會忽略 +0 和 -0,也不會把 NaN 等于 NaN。
console.log(Object.is(1,1));//true
console.log(Object.is(NaN,NaN));//true , == 和 === 返回false
console.log(Object.is(0,-0));//false , == 和 === 返回trueconsole.log("\n----------分割線----------\n");
Object.preventExtensions(obj),Object.isExtensible(obj)
Object.preventExtensions(obj)可以防止新屬性被添加到obj中(即防止該對象被擴展)。它還可以防止對象的原型被重新指定。
Object.isExtensible(obj)返回布爾值,判斷對象是否可擴展(是否可以添加新的屬性)。
在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
// Object.preventExtensions(obj) 靜態方法可以防止新屬性被添加到obj中(即防止該對象被擴展)。它還可以防止對象的原型被重新指定。
// 在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
// Object.isExtensible(obj) 返回布爾值,判斷對象是否可擴展(是否可以添加新的屬性)。
// 在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
const extensibleObj = Object.preventExtensions({name:'Tom'});console.log(Object.isExtensible(extensibleObj));//false,不可擴展
console.log(Object.isExtensible({name:'Tom'}));//true
console.log(Object.isExtensible(1));//falseconsole.log("\n----------分割線----------\n");
?
Object.freeze(obj)
凍結obj對象并將其返回,
凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,
即這個對象本身以及屬性都不能在修改(新增、刪除、添加、修改),但是,當屬性是引用類型時可以修改引用類型內的屬性和值(淺凍結,只影響一層)
// Object.freeze(obj) 凍結obj對象并將其返回,
// 凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,
// 即這個對象本身以及屬性都不能在修改(新增、刪除、添加、修改),但是,當屬性是引用類型時可以修改引用類型內的屬性和值(淺凍結,只影響一層)const obj5 = {//注意區分常量和凍結,常量表示的是obj5不能被復制,內部任然可以修改,(淺)凍結是內部的(一層)屬性不能被修改name:'Tom',age:18,info:{//此處內部不受淺凍結影響,若要深凍結則需要遍歷引用類型屬性凍結address:'beijing'}
}console.log(Object.freeze(obj5) === obj5);//{name:'Tom',age:18},返回凍結后的對象,和原對象一致
Object.isFrozen(obj)
返回布爾值,判斷對象是否被凍結。
在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
// Object.isFrozen(obj) 返回布爾值,判斷對象是否被凍結。
// 在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
const freezeObj = Object.freeze({name:'Tom'});
console.log(Object.isFrozen(freezeObj));//true
console.log(Object.isFrozen({name:'Tom'}));//false
console.log(Object.isFrozen(1));//falseconsole.log("\n----------分割線----------\n");
?
?Object.seal(obj),Object.isSealed(obj)
Object.seal(obj) 返回傳遞的對象,使obj密封。
Object.isSealed(obj) 返回布爾值,判斷對象是否被密封(不能添加,刪除,修改)。
在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
// Object.seal(obj) 返回傳遞的對象,使obj密封。
// Object.isSealed(obj) 返回布爾值,判斷對象是否被密封(不能添加,刪除,修改)。
// 在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
const sealObj = Object.seal({name:'Tom'});
console.log(Object.isSealed(sealObj));//true
console.log(Object.isSealed({name:'Tom'}));//falseconsole.log("\n----------分割線----------\n");
?Object.keys(obj)
返回一個包含所有自有可枚舉(可遍歷)屬性名稱的數組。obj:待查詢的對象,傳入基本類型返回空數組[]
// Object.keys(obj) 返回一個包含所有自有可枚舉(可遍歷)屬性名稱的數組。obj:待查詢的對象,傳入基本類型返回空數組[]console.log(Object.keys({name:'Tom',age:18}));//['name','age']console.log("\n----------分割線----------\n");
?Object.values(obj)
返回一個包含所有自有可枚舉(可遍歷)屬性值的數組。obj:待查詢的對象,傳入基本類型返回空數組[]
// Object.values(obj) 返回一個包含所有自有可枚舉(可遍歷)屬性值的數組。obj:待查詢的對象,傳入基本類型返回空數組[]console.log(Object.values({name:'Tom',age:18}));//['Tom',18]console.log("\n----------分割線----------\n");
?Object.setPrototypeOf(obj, prototype)
設置對象obj的原型為prototype,并返回該對象。
通常,作為正確的方式,應該使用 Object.setPrototypeOf() 方法來設置對象的原型。因為 Object.prototype.__proto__ 訪問器已被棄用。
如果傳入基本類型,則直接返回該基本類型,不進行任何其他操作
更改對象的 [[Prototype]] 在各個瀏覽器和 JavaScript 引擎上都是一個很慢的操作,要顧及性能應避免修改原型屬性
// Object.setPrototypeOf(obj, prototype),設置對象obj的原型為prototype,并返回該對象。
// 通常,作為正確的方式,應該使用 Object.setPrototypeOf() 方法來設置對象的原型。因為 Object.prototype.__proto__ 訪問器已被棄用。
// 如果傳入基本類型,則直接返回該基本類型,不進行任何其他操作
// 更改對象的 [[Prototype]] 在各個瀏覽器和 JavaScript 引擎上都是一個很慢的操作,要顧及性能應避免修改原型屬性const ob = {"0":0,"1":1}
Object.setPrototypeOf(ob,Array.prototype);
console.log(ob);//Array { '0': 0, '1': 1 }
方法總覽
// 新建一個對象const obj = {//通過{}name:'Tom',age:18
}
const obj1 = new Object({//通過構造函數name:'Tom',age:18
})
const obj2 = Object.create({ //通過靜態方法name:'Tom',age:18
})//注意這里的參數不是生成對象的結果,參數會作為obj2的原型,obj2本身是一個新的空對象console.log(obj,obj1,obj2);console.log("\n----------分割線----------\n");// 實例屬性// constructor 對象的實例屬性
// 除了 null 原型對象之外,任何對象都會在其 [[Prototype]] 上有一個 constructor 屬性。
// Object 實例的 constructor 數據屬性返回一個引用,指向創建該實例對象的構造函數(函數本身而不是字符串)
// 可以用來判斷對象類型
const arr = [];
const number = 1;
console.log(obj.constructor === Object);//true
console.log(arr.constructor === Array);//true
console.log(number.constructor === Number);//trueconsole.log("\n----------分割線----------\n");// 實例方法// hasOwnProperty(key) 方法會返回一個布爾值,如果自身有這個key屬性(不包括原型中繼承的屬性),則返回 true,否則返回 false。
console.log({name:'Tom'}.hasOwnProperty('name'));//true
console.log({name:undefined}.hasOwnProperty('name'));//true,這里的name值雖然是undefined,但是屬性存在
console.log(['Tom'].hasOwnProperty('0'));//true,數組也是對象,可以將索引看成key
console.log([].hasOwnProperty('length'));//true,數組固有的屬性lengthconsole.log("\n----------分割線----------\n");// isPrototypeOf(obj) 返回布爾值 判斷當前對象是否在obj的原型鏈中,(對象---原型鏈)
// 和object instanceof AFunction不同,這是比較兩個對象的原型鏈 ,(原型鏈---原型鏈)
console.log(Object.prototype.isPrototypeOf({}));//true,Object出現在{}的原型鏈中
console.log(Array.prototype.isPrototypeOf([]));//true,Array出現在[]的原型鏈中console.log("\n----------分割線----------\n");// propertyIsEnumerable(prop) 方法返回一個布爾值,表示prop是否是對象的可枚舉自有屬性(遍歷時是否會被訪問,能否出現在for in循環中)
// 大多數內置屬性默認情況下是不可枚舉的,而用戶創建的對象屬性通常是可枚舉的,除非明確指定為不可枚舉。
console.log({name:'Tom'}.propertyIsEnumerable('name'));//true,name屬性可以遍歷
console.log(['0'].propertyIsEnumerable('0'));//true,索引屬性可以遍歷
console.log(['0'].propertyIsEnumerable('length'));//false,length屬性不可遍歷console.log("\n----------分割線----------\n");// toLocaleString() 返回一個字符串,返回調用toString()的結果(return this.toString())
console.log({name:'Tom'}.toLocaleString());//"[object Object]"console.log("\n----------分割線----------\n");// toString() 返回一個表示該對象的字符串。打印實例時默認調用該方法
console.log({name:'Tom'}.toString());//"[object Object]"console.log("\n----------分割線----------\n");// valueOf() 返回指定對象的原始值。值傳遞時可以使用valueOf將值提取出來
const obj3 = {name:'Tom'}
let newObj = obj3.valueOf();// 值傳遞,此時newObj和obj3并不是指向同一個內存
console.log(obj3.valueOf());// {name:'Tom'},返回對象本身的值
console.log(obj3.valueOf() === obj3);//trueconsole.log("\n----------分割線----------\n");// 靜態方法// Object.assign(target, ...sources) 將source中所有可以遍歷的鍵值對,放入target中,返回target
// target和source中相同的key,source中的值會覆蓋target中的值
// target 待修改的對象 ,source 多個對象
console.log(Object.assign({},{name:'tom'},{age:'10'}));// {name:'tom',age:'10'}
console.log(Object.assign({},[1,2,3,4]));// {0:1,1:2,2:3,3:4}
console.log(Object.assign({},[1,2,3,4],'sss'));// { '0': 's', '1': 's', '2': 's', '3': 4 },字符串會被拆分成單個字符作為對象,后面的屬性值會覆蓋前面的console.log("\n----------分割線----------\n");// Object.create(proto) 靜態方法以proto作為原型,創建一個新對象。
const obj4 = Object.create([]);//以[]作為原型,創建一個新對象,數組對象
console.log(obj4);//Array {}console.log("\n----------分割線----------\n");// Object.defineProperties(obj, props) 靜態方法直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,并返回這個對象。
// obj:在其上定義或修改屬性的對象; props: 一個對象,其中每個鍵表示要定義或修改的屬性的名稱,每個值是描述該屬性的對象(是否只讀,是否可枚舉遍歷,)
console.log(Object.defineProperties({name:'Tom'
},
{//屬性描述對象name:{value:'Jerry',writable:true //可讀寫}
}));//{name:'Jerry'}console.log("\n----------分割線----------\n");// Object.defineProperty(obj, prop, descriptor) 靜態方法會直接在obj上定義一個新屬性prop,或修改其現有屬性prop,并返回此對象。
// obj:待修改的對象 prop:obj對象待修改的屬性名 descriptor:屬性描述對象
console.log(Object.defineProperty({name:'Tom'},'name',{value:'Jerry'}));//{name:'Jerry'}console.log("\n----------分割線----------\n");// Object.entries(obj) 返回一個obj自身可枚舉(可遍歷)屬性的鍵值對數組(元組),
// 其排列與使用 for...in 循環遍歷該對象時返回的順序一致(區別在于 for...in 循環還會枚舉其原型鏈中的屬性)。
console.log(Object.entries({name:'Tom',age:18}));//[["name","Tom"],["age",18]]console.log("\n----------分割線----------\n");// Object.fromEntries(iterable) 將鍵值對列表(iterable)轉換為一個對象。
// iterable:一個包含對象列表的可迭代對象,例如 Array 或者 Map。
// 每個對象都要有兩個屬性,0:表示屬性鍵的字符串或者 Symbol。1:屬性值。通常,該對象被實現為二元數組,第一個元素是屬性鍵,第二個元素是屬性值。console.log(Object.fromEntries([['name','Tom'],['age',18]]));//{name:'Tom',age:18}console.log("\n----------分割線----------\n");// Object.getOwnPropertyDescriptor(obj, prop) 返回obj上一個自有屬性prop對應的屬性描述對象,如果obj上沒有prop屬性返回undefined。
// obj:待查詢的對象 prop:string或者symbol 待查詢的屬性名console.log(Object.getOwnPropertyDescriptor({name:'Tom'},'name'));
//{value:'Tom',writable:true,enumerable:true,configurable:true}console.log("\n----------分割線----------\n");// Object.getOwnPropertyDescriptors(obj) 返回obj的所有自有屬性屬性描述對象。obj:待查詢的對象,類似于Object.getOwnPropertyDescriptorconsole.log(Object.getOwnPropertyDescriptors({name:'Tom',age:18}));//{name:{...},age:{...}}console.log("\n----------分割線----------\n");// Object.getOwnPropertyNames(obj) 返回obj對象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol屬性)組成的數組。console.log(Object.getOwnPropertyNames({name:'Tom',age:18}));//['name','age']console.log("\n----------分割線----------\n");// Object.getOwnPropertySymbols(obj) 返回obj對象自身的所有 Symbol 屬性的數組。console.log(Object.getOwnPropertySymbols({[Symbol('name')]:1,[Symbol('age')]:2, name:'Tom',age:18}));//[Symbol(name),Symbol(age)]console.log("\n----------分割線----------\n");// Object.getPrototypeOf(obj) 返回obj對象的原型對象。即內部 [[Prototype]] 屬性的值console.log(Object.getPrototypeOf({}));//Object
console.log(Object.getPrototypeOf([]));//Arrayconsole.log("\n----------分割線----------\n");// Object.groupBy(item, callback) 返回一個對象,對象內根據callback的返回值,將item進行分類。2024新增
// item:待分類的可迭代對象 callback:回調函數,返回值作為分類的依據// const items = [
// { name: "蘆筍", type: "蔬菜", quantity: 5 },
// { name: "香蕉", type: "水果", quantity: 0 },
// { name: "山羊", type: "肉", quantity: 23 },
// { name: "櫻桃", type: "水果", quantity: 5 },
// { name: "魚", type: "肉", quantity: 22 },
// ];
// const result = Object.groupBy(items, ({type}) => type);//此方法目前只在瀏覽器支持
// console.log(result);//{蔬菜:{...},水果:{...},肉:{...}}// Object.hasOwn(obj, prop) 返回布爾值,檢查obj對象自身是否具有指定的屬性prop。Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()。console.log(Object.hasOwn({name:'Tom'},'name'));//trueconsole.log("\n----------分割線----------\n");// Object.is(value1, value2) 返回布爾值,判斷兩個值是否為同一個值。
// Object.is() 與 == 運算符并不等價, 也不等價于 === 運算符,相比于 == Object.is()轉換類型比較,相比于 === Object.is()不會忽略 +0 和 -0,也不會把 NaN 等于 NaN。
console.log(Object.is(1,1));//true
console.log(Object.is(NaN,NaN));//true , == 和 === 返回false
console.log(Object.is(0,-0));//false , == 和 === 返回trueconsole.log("\n----------分割線----------\n");// Object.preventExtensions(obj) 靜態方法可以防止新屬性被添加到obj中(即防止該對象被擴展)。它還可以防止對象的原型被重新指定。
// 在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
// Object.isExtensible(obj) 返回布爾值,判斷對象是否可擴展(是否可以添加新的屬性)。
// 在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
const extensibleObj = Object.preventExtensions({name:'Tom'});console.log(Object.isExtensible(extensibleObj));//false,不可擴展
console.log(Object.isExtensible({name:'Tom'}));//true
console.log(Object.isExtensible(1));//falseconsole.log("\n----------分割線----------\n");// Object.freeze(obj) 凍結obj對象并將其返回,
// 凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,
// 即這個對象本身以及屬性都不能在修改(新增、刪除、添加、修改),但是,當屬性是引用類型時可以修改引用類型內的屬性和值(淺凍結,只影響一層)const obj5 = {//注意區分常量和凍結,常量表示的是obj5不能被復制,內部任然可以修改,(淺)凍結是內部的(一層)屬性不能被修改name:'Tom',age:18,info:{//此處內部不受淺凍結影響,若要深凍結則需要遍歷引用類型屬性凍結address:'beijing'}
}console.log(Object.freeze(obj5) === obj5);//{name:'Tom',age:18},返回凍結后的對象,和原對象一致// Object.isFrozen(obj) 返回布爾值,判斷對象是否被凍結。
// 在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
const freezeObj = Object.freeze({name:'Tom'});
console.log(Object.isFrozen(freezeObj));//true
console.log(Object.isFrozen({name:'Tom'}));//false
console.log(Object.isFrozen(1));//falseconsole.log("\n----------分割線----------\n");// Object.seal(obj) 返回傳遞的對象,使obj密封。
// Object.isSealed(obj) 返回布爾值,判斷對象是否被密封(不能添加,刪除,修改)。
// 在ES5中傳入的值不是對象會直接報錯,在ES6中傳入的值不是對象會返回false
const sealObj = Object.seal({name:'Tom'});
console.log(Object.isSealed(sealObj));//true
console.log(Object.isSealed({name:'Tom'}));//falseconsole.log("\n----------分割線----------\n");// Object.keys(obj) 返回一個包含所有自有可枚舉(可遍歷)屬性名稱的數組。obj:待查詢的對象,傳入基本類型返回空數組[]console.log(Object.keys({name:'Tom',age:18}));//['name','age']console.log("\n----------分割線----------\n");// Object.values(obj) 返回一個包含所有自有可枚舉(可遍歷)屬性值的數組。obj:待查詢的對象,傳入基本類型返回空數組[]console.log(Object.values({name:'Tom',age:18}));//['Tom',18]console.log("\n----------分割線----------\n");// Object.setPrototypeOf(obj, prototype),設置對象obj的原型為prototype,并返回該對象。
// 通常,作為正確的方式,應該使用 Object.setPrototypeOf() 方法來設置對象的原型。因為 Object.prototype.__proto__ 訪問器已被棄用。
// 如果傳入基本類型,則直接返回該基本類型,不進行任何其他操作
// 更改對象的 [[Prototype]] 在各個瀏覽器和 JavaScript 引擎上都是一個很慢的操作,要顧及性能應避免修改原型屬性const ob = {"0":0,"1":1}
Object.setPrototypeOf(ob,Array.prototype);
console.log(ob);//Array { '0': 0, '1': 1 }