@(JavaScript基礎)
JavaScript內置對象: Object
Object對象(或Object構造函數)
屬性:
-----------------------------------------------------------------------------------
Object.length:
值為1
-----------------------------------------------------------------------------------
Object.propotype:
表示Object的原型對象
Object.propotype.__proto__ 表示Object的原型對象的原型對象,即null
Object.propotype.constructor 表示Object的原型對象的構造函數,即構造函數Object
Object.prototype屬性的屬性特性:
數據描述符和存取描述符均具有以下可選鍵值:
configurable:
當且僅當該屬性的 configurable 為 true 時,該屬性描述符才能夠被改變,
可以使用delete刪除屬性,以及除writable特性外的其他特性可以被修改
默認為 false
enumerable:
當且僅當該屬性的enumerable為true時,該屬性才能夠出現在對象的枚舉屬性中。
默認為 false
數據描述符同時具有以下可選鍵值:
value:
該屬性對應的值。默認為 undefined。
writable:
當且僅當該屬性的writable為true時,該屬性才能被賦值運算符改變
默認為 false
存取描述符同時具有以下可選鍵值:
get:
一個給屬性提供 getter 的方法,如果沒有 getter 則為 undefined。
該方法返回值被用作屬性值。默認為 undefined。
注意:該方法無參數
set:
一個給屬性提供 setter 的方法,如果沒有 setter 則為 undefined。
該方法將接受唯一參數,并將該參數的新值分配給該屬性。默認為 undefined
-----------------------------------------------------------------------------------
方法:
-----------------------------------------------------------------------------------
Object.create(proto[, propertiesObject]):
描述:
使用指定的原型對象和屬性創建一個新對象
參數:
proto:
新創建對象的原型對象
propertiesObject:
如果沒有指定為 undefined,則是要添加到新創建對象的可枚舉屬性
這些屬性對應Object.defineProperties()的第二個參數
返回值:
在指定原型對象上添加新屬性后的對象
例子:
const obj={name:'lee'};
const newObj=Object.create(obj);
console.log(obj); // {name:'lee'}
console.log(obj.name); // "lee"
const newObject=Object.create(obj,{
age:{
value:18
},
hobby:{
value:'read'
}
});
console.log(newObject); // {age: 18, hobby: "read"}
-----------------------------------------------------------------------------------
Object.defineProperty(obj, prop, descriptor)
描述:
給對象添加一個屬性并指定該屬性的配置
參數:
obj
prop
descriptor:
描述符對象
返回值:
被傳遞給函數的對象
例子:
const o={
name:'lee',
_age:12
};
// 等價于
Object.defineProperty(o,'name',{
value:'lee',
writable : true,
configurable : true,
enumerable : true
}); {name:"lee"}
Object.defineProperty(o,'age',{
get:function(){
return this._age;
},
set:function(value){
console.log(value,'set')
return value*2;
},
enumerable:true,
configurable:true
});
console.log(o.age); // 12
o.age=18; // 18 set
console.log(o.age); // 12
// 注意:存取描述符的值只能通過set函數來設置
-----------------------------------------------------------------------------------
Object.defineProperties(obj, props):
描述:
給對象添加多個屬性并分別指定它們的配置
參數:
obj
props
返回值:
被傳遞給函數的對象
例子:
const obj={};
Object.defineProperties(obj,{
name:{
value:"lee",
writable : true,
configurable : true,
enumerable : true
},
age:{
value:18,
writable : true,
configurable : true,
enumerable : true
}
}); // {name: "lee", age: 18}
-----------------------------------------------------------------------------------
Object.is(value1, value2):
描述:
比較兩個值是否相同。所有 NaN 值都相等(這與==和===不同)
如果下列任何一項成立,則兩個值相同:
兩個值都是 undefined
兩個值都是 null
兩個值都是 true 或者都是 false
兩個值是由相同個數的字符按照相同的順序組成的字符串
兩個值指向同一個對象
兩個值都是數字并且
都是正零 +0
都是負零 -0
都是 NaN
都是除零和 NaN 外的其它同一個數字
參數:
value1
value2
返回值:
boolean值
例子:
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
// 特例
Object.is(0, -0); // false
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
-----------------------------------------------------------------------------------
Object.assgin( target,...sources ):
描述:
用于將所有可枚舉屬性的值從一個或多個源對象復制到目標對象,
參數:
target:
目標對象
sources:
源對象
返回值:
返回目標對象
例子:
const obj={},
source={a:1},
arr=[2,3];
Object.assign(obj,source,arr); // {0: 2, 1: 3, a: 1}
總結:
該方法常用來將一個多個對象的鍵值對復制到空對象中去
-----------------------------------------------------------------------------------
Object.preventExtensions(obj):
描述:
防止對象的任何擴展
參數:
obj:
將要變得不可擴展的對象
返回值:
已經不可擴展的對象
例子:
const obj={};
const newObj=Object.create(obj);
newObj.name='lee';
newObj.age=18;
Object.preventExtensions(newObj);
Object.getOwnPropertyDescriptors(newObj);
// {
// age:{
// value: 18,
// writable: true,
// enumerable: true,
// configurable: true // 調用preventExtensions方法后的對象屬性仍然可以配置
// },
// name:{
// value: "lee",
// writable: true,
// enumerable: true,
// configurable: true
// }
// }
newObj.hobby='read';
console.log(newObj); // {name: "lee", age: 18}
delete newObj.name;
console.log(newObj); // {age: 18}
obj.name='panda';
console.log(newObj.name); // 'lee'
-----------------------------------------------------------------------------------
Object.seal(obj):
描述:
可以讓一個對象密封,并返回被密封后的對象。
密封對象將會阻止向對象添加新的屬性,并且會將所有已有屬性的可配置性(configurable)置為不可配置(false),即不可修改屬性的描述或刪除屬性。
但是可寫性描述(writable)為可寫(true)的屬性的值仍然可以被修改
參數:
obj
返回值:
將要被密封的對象
例子:
const obj={};
const newObj=Object.create(obj);
newObj.name='lee';
newObj.age=18;
Object.seal(newObj);
Object.getOwnPropertyDescriptors(newObj);
// {
// age:{
// value: 18,
// writable: true,
// enumerable: true,
// configurable: false // 調用seal方法后的對象屬性仍然不可配置
// },
// name:{
// value: "lee",
// writable: true,
// enumerable: true,
// configurable: false
// }
// }
newObj.hobby='read';
console.log(newObj); // {name: "lee", age: 18}
delete newObj.name;
console.log(newObj); // {name: "lee", age: 18}
newObj.name='panda';
console.log(newObj.name); // 'panda'
-----------------------------------------------------------------------------------
Object.freeze(obj):
描述:
凍結對象:其他代碼不能刪除或更改任何屬性,
如果一個屬性的值是個對象,則這個對象中的屬性是可以修改的,除非它也是個凍結對象
參數:
obj
返回值:
被凍結的對象
例子:
const obj={};
const newObj=Object.create(obj);
newObj.name='lee';
newObj.age=18;
Object.freeze(newObj);
Object.getOwnPropertyDescriptors(newObj);
// {
// age:{
// value: 18,
// writable: false, // 調用freeze方法后的對象屬性不可更改
// enumerable: true,
// configurable: true // 調用freeze方法后的對象屬性不可配置
// },
// name:{
// value: "lee",
// writable: false,
// enumerable: true,
// configurable: true
// }
// }
newObj.hobby='read';
console.log(newObj); // {name: "lee", age: 18}
delete newObj.name;
newObj.name='panda';
console.log(newObj); // {name: "lee", age: 18}
newObj.name='panda';
console.log(newObj.name); // 'lee'
// 深凍結
function deepFreeze(obj){
var propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function(name) {
var prop = obj[name];
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
return Object.freeze(obj);
};
const o={person:{name:'lee'}};
deepFreeze(o);o.person.name='zz';
console.log(o.person.name); // 'lee'
-----------------------------------------------------------------------------------
Object.isExtensible(obj):
描述:
判斷對象是否可擴展,是否可以在它上面添加新的屬性
默認情況下,對象是可擴展的:即可以為他們添加新的屬性。
以及它們的 __proto__ 屬性可以被更改。
Object.preventExtensions,Object.seal 或 Object.freeze 方法都可以標記一個對象為不可擴展
參數:
obj
返回值:
boolean值
例子:
const obj={};
Object.isExtensible(obj); // true
// ...可以變的不可擴展.
Object.preventExtensions(obj);
Object.isExtensible(obj); // false
// 密封對象是不可擴展的.
Object.seal(obj);
Object.isExtensible(obj); // false
// 凍結對象也是不可擴展.
Object.freeze(obj);
Object.isExtensible(obj); // false
-----------------------------------------------------------------------------------
Object.isSealed(obj):
描述:
如果這個對象是密封的,則返回 true,否則返回 false
密封對象是指那些不可 擴展 的,且所有自身屬性都不可配置且因此不可刪除(但不一定是不可寫)的對象
參數:
obj
返回值:
boolean
例子:
const obj={name:'lee'};
Object.preventExtensions(obj);
obj.age=18;
console.log(obj)
-----------------------------------------------------------------------------------
Object.isFrozen(obj):
描述:
判斷對象是否已經凍結
一個對象是凍結的是指它不可擴展,所有屬性都是不可配置的,
且所有數據屬性(即沒有getter或setter組件的訪問器的屬性)都是不可寫的
參數:
obj
返回值:
boolean
例子:
const obj={};
Object.isSealed(obj); // false
// ...可以變的不可擴展.
Object.preventExtensions(obj);
Object.isSealed(obj); // true
// 密封對象是不可擴展的.
Object.seal(obj);
Object.isSealed(obj); // true
// 凍結對象也是不可擴展.
Object.freeze(obj);
Object.isSealed(obj); // true
-----------------------------------------------------------------------------------
獲取對象屬性描述符對象
Object.getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor(obj, prop):
描述:
返回對象指定的屬性配置
參數:
obj
prop
返回值:
如果指定的屬性存在于對象上,則返回其屬性描述符對象(property descriptor),
否則返回 undefined
例子:
-----------------------------------------------------------------------------------
Object.getOwnPropertyDescriptors
Object.getOwnPropertyDescriptors(obj):
描述:
返回對象指定的屬性配置
參數:
obj
返回值:
所指定對象的所有自身屬性的描述符,如果沒有任何自身屬性,則返回空對象
例子:
const obj={};
const newObj=Object.create(obj);
newObj.name='lee';
newObj.age=18;
Object.getOwnPropertyDescriptors(newObj);
// {
// age:{
// value: 18,
// writable: true,
// enumerable: true,
// configurable: true
// },
// name:{
// value: "lee",
// writable: true,
// enumerable: true,
// configurable: true
// }
// }
凍結或密封或阻止對象擴展詳解:
總結:
不可擴展:
阻止添加自身的屬性,但屬性仍然可以添加到對象原型
不可擴展對象的屬性仍然可被刪除
密封對象:
是指那些不可 擴展 的,且所有自身屬性都不可配置且因此不可刪除(但不一定是不可寫,可寫性描述(writable)為可寫(true)的屬性的值仍然可以被修改)的對象
凍結對象:
凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可配置性、可寫性。(可枚舉性是可以修改的,官網有誤)
也就是說,這個對象永遠是不可變的
枚舉方法:
從 ECMAScript 5 開始,有三種原生的方法用于列出或枚舉對象的屬性:
for...in 循環
該方法依次訪問一個對象及其原型鏈中所有可枚舉的屬性。(原型鏈+可枚舉)
Object.keys(o)
該方法返回一個對象 o 自身包含(不包括原型中)的所有屬性的名稱的數組。(可枚舉)
Object.getOwnPropertyNames(o)
該方法返回一個數組,它包含了對象 o 所有擁有的屬性(無論是否可枚舉)的名稱。(所有屬性,不論是否枚舉)
Object.getOwnPropertySymbols(obj):
該方法返回一個數組,它包含了指定對象自身所有的符號屬性。(符號屬性)
Object.entries(obj):
該方法返回給定對象自身可枚舉屬性的[key, value]數組
例子:
const o={
sex:'boy',
weight:'60kg'
};
let age=Symbol('age');
const newObj=Object.create(o)
Object.defineProperties(newObj,{
'name':{
value:'lee',
writable:true,
enumerable:true,
configurable:true,
},
'hobby':{
value:'read',
writable:true,
enumerable:true,
configurable:true,
},
[age]:{
value:18,
writable:true,
enumerable:false,
configurable:true,
},
'friend':{
value:'Jack',
writable:true,
enumerable:false,
configurable:true,
},
});
const arr=[];
for(let v in newObj){
arr.push(v)
};
console.log(arr); // ["name", "hobby", "sex", "weight"]
const arr2=Object.keys(newObj);
console.log(arr2); // ["name", "hobby"]
const arr3=Object.getOwnPropertyNames(newObj);
console.log(arr3); // ["name", "hobby", "friend"]
const arr4=Object.getOwnPropertySymbols(newObj);
console.log(arr4); // [Symbol(age)]
const arr5=Object.entries(newObj);
console.log(arr5); // [["name", "lee"],["hobby", "read"]]
-----------------------------------------------------------------------------------
Object.keys(obj):
描述:
返回一個由一個給定對象的自身可枚舉屬性組成的數組,
數組中屬性名的排列順序和使用 for...in 循環遍歷該對象時返回的順序一致
(兩者的主要區別是 一個 for-in 循環還會枚舉其原型鏈上的屬性)
參數:
obj
返回值:
一個表示給定對象的所有可枚舉屬性的字符串數組
例子:
const obj={name:'lee'};
const newObj=Object.create(obj);
newObj.age=18;
console.log(Object.keys(newObj)); // ['name']
const arr=[];
for(let v in newObj){
arr.push(v);
}
console.log(arr); // ['name','age']
-----------------------------------------------------------------------------------
Object.getOwnPropertyNames(obj):
描述:
返回一個數組,它包含了指定對象所有的可枚舉或不可枚舉的屬性名
參數:
obj
返回值:
在給定對象上找到的屬性對應的字符串數組
例子:
const arr=['a','b','c','d'];
Object.getOwnPropertyNames(arr); // ["0", "1", "2", "3", "length"]
const arr={0:'a',1:'b',2:'c'};
console.log(Object.getOwnPropertyNames(arr)); // ["0", "1", "2"]
const obj={name:'lee',age:18};
console.log(Object.getOwnPropertyNames(obj)); // ["name", "age"]
-----------------------------------------------------------------------------------
Object.getOwnPropertySymbols(obj):
描述:
返回一個數組,它包含了指定對象自身所有的符號屬性
參數:
obj
返回值:
在給定對象自身上找到的所有 Symbol 屬性的數組
例子:
const obj={};
let a=Symbol('a');
let b=Symbol('b');
obj[a]='name';
obj[b]='age';
obj.hobby='read';
Object.getOwnPropertySymbols(obj); // [Symbol(a), Symbol(b)]
-----------------------------------------------------------------------------------
Object.values(obj):
描述:
返回給定對象自身可枚舉值的數組
參數:
obj
返回值:
Object.values()返回一個數組,其元素是在對象上找到的枚舉屬性值
例子:
const obj={name:'lee',age:18};
Object.values(obj); // ["lee", 18]
-----------------------------------------------------------------------------------
Object.entries(obj):
描述:
返回給定對象自身可枚舉屬性的[key, value]數組
參數:
obj
返回值:
給定對象自身可枚舉屬性的鍵值對數組
例子:
const obj={name:"lee",age:18};
Object.entries(obj)); //[['name','lee'],['age',18]]
獲取或設置對象的原型對象
-----------------------------------------------------------------------------------
Object.getPrototypeOf(obj):
描述:
返回指定對象的原型對象
參數:
obj
返回值:
給定對象的原型。如果沒有繼承屬性,則返回 null
例子:
const proto=null;
const obj=Object.create(proto); // {}
Object.getPrototypeOf(obj)==null; // true
-----------------------------------------------------------------------------------
Object.setPrototypeOf(obj, prototype):
描述:
設置一個指定的對象的原型 ( 即, 內部[[Prototype]]屬性)到另一個對象或 null
參數:
obj:
要設置其原型的對象
prototype:
該對象的新原型(一個對象 或 null)
返回值:
要設置其原型的對象
例子:
const obj={};
const proto={name:'lee',age:18};
Object.setPrototypeOf(obj,proto);
console.log(obj.__proto__); // {name: "lee", age: 18}
-----------------------------------------------------------------------------------
Object.prototype
屬性:
-----------------------------------------------------------------------------------
Object.prototype.constructor
特定的函數,用于創建一個對象的原型
-----------------------------------------------------------------------------------
Object.prototype.__proto__
指向當對象被實例化的時候,用作原型的對象
-----------------------------------------------------------------------------------
方法:
-----------------------------------------------------------------------------------
Object.prototype.hasOwnProperty(prop):
描述:
返回一個布爾值 ,表示某個對象是否含有指定的屬性,而且此屬性非原型鏈繼承的。
參數:
prop
返回值:
boolean值
-----------------------------------------------------------------------------------
Object.prototype.isPrototypeOf(obj)
描述:
返回一個布爾值,表示指定的對象是否在本對象的原型鏈中
參數:
obj
返回值:
boolean值
-----------------------------------------------------------------------------------
Object.prototype.propertyIsEnumerable()
判斷指定屬性是否可枚舉,內部屬性設置參見 ECMAScript [[Enumerable]] attribute 。
Object.prototype.toLocaleString()
直接調用 toString()方法。
Object.prototype.toString()
返回對象的字符串表示。
Object.prototype.valueOf()
-----------------------------------------------------------------------------------