屬性的簡潔表示法
ES6 允許在大括號裡面直接寫入變數和函式,作為物件的屬性和方法。這樣的書寫更加簡潔。
const foo = 'bar';
const baz = {
foo
};
console.log(baz); // { foo: 'bar' }
function f(name, age) {
return {
name,
age
};
}
// 等同於
// function f(name, age) {
// return {
// name: name,
// age: age
// };
// }
console.log('資訊', f('李四', 23));
// 輸出的資訊是 {age: 23 name: "李四"}
let birth = '2022-3-27';
const Person = {
name: '張三',
//等同於birth: birth
birth,
// 等同於hello: function (){}
hello() {
console.log('我的名字叫:', this.name);
}
};
// Person.hello(); // 我的名字叫:張三
//沒有返回值時,預設返回 undefined。下面這一條語句會被執行兩次
console.log('資訊', Person.hello());
// 第1次的值: 我的名字叫:張三
// 第2次的值: undefined
注意,簡寫的物件方法不能用作建構函式,會報錯。
let Person = {
name: '張三',
hello: function() {
console.log('你好呀')
},
like() {
console.log('簡寫的物件方法不能用作建構函式==>error會報錯')
}
};
new Person.hello() // 不會報錯
new Person.like(); //會報錯
ES6物件屬性遍歷的5種方式
ES6 一共有 5 種方法可以遍歷物件的屬性。
1==>for...in
for...in迴圈遍歷物件自身的和繼承的可列舉屬性(不含 Symbol 屬性)。
const obj = { h: 180,w: 125}
for (let keysName in obj) {
console.log(keysName);
// h w 輸出的是key值哈
}
2==>Object.keys(obj)
Object.keys返回一個陣列,
包括物件自身的(不含繼承的)所有可列舉屬性(不含 Symbol 屬性)的鍵名。
const obj = {
height: 180,
weight: 125,
}
console.log(Object.keys(obj)) //['height', 'weight']
3==>Object.getOwnPropertyNames(obj) 【瞭解即可】
Object.getOwnPropertyNames返回一個陣列,
包含物件自身【所有的屬性】。[其自身的可列舉和不可列舉屬性的名稱被返回]
【不含 Symbol 屬性】的鍵名。
let obj = {};
let a = Symbol("a");
let b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
let objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols.length); // 2
console.log(objectSymbols) // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]) // Symbol(a)
4==>Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一個陣列,包含物件自身的所有 Symbol 屬性的鍵名。
5==>Reflect.ownKeys(obj)
Reflect.ownKeys返回一個陣列,包含物件自身的(不含繼承的)所有鍵名。
不管鍵名是 Symbol 或字串,也不管是否可列舉。
const obj = {
height: 180,
weight: 125,
}
console.log(Reflect.ownKeys(obj))
//['height', 'weight']
以上的 5 種方法遍歷物件的鍵名,都遵守同樣的屬性遍歷的次序規則。
JavaScript中的可列舉屬性與不可列舉屬性
在JavaScript中,物件的屬性分為可列舉和不可列舉之分,
它們是由屬性的 enumerable 值決定的。
可列舉性決定了這個屬效能否被for…in查詢遍歷到。
屬性的列舉性會影響以下三個函式的結果:
for…in
Object.keys()
JSON.stringify
Object.is()
ES5 比較兩個值是否相等,只有兩個運算子。
相等運算子(==)和嚴格相等運算子(===)。
它們都有缺點,前者會自動轉換資料型別。
後者的NaN不等於自身,以及+0等於-0。
JavaScript 缺乏一種運算,只要兩個值是一樣的,它們就應該相等。
於是,ES6提出來了一種同值相等的演算法,來解決這個問題。
console.log('==>', Object.is('bar', 'bar'))
// true
console.log(Object.is({}, {}))
// false
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.assign物件合併
Object.assign()方法用於物件的合併。
將源物件(source)的所有可列舉屬性,複製到目標物件(target。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 ,b:22};
Object.assign(target, source1, source2);
target // {a:1, b:22, c:3}
Object.assign需要注意的點
需要注意的點:Object.assign()方法的第一個引數是目標物件,後面的引數都是源物件。
由於undefined和null無法轉成物件,所以如果它們作為引數,就會報錯。
Object.assign(undefined) // 報錯
Object.assign(null) // 報錯
如果非物件引數出現在源物件的位置即非首引數,
那麼處理規則有所不同。
首先,這些引數都會轉成物件,如果無法轉成物件,就會跳過。
這意味著,如果undefined和null不在首引數,就不會報錯。
let obj = {a: 1};
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true
特別注意:其他型別的值(即數值、布林值)不在首引數,也不會報錯。
但是,除了字串會以陣列形式,拷貝入目標物件。
-- 字串會以陣列形式拷貝入目標物件
const str1 = 'abc';
const obj = Object.assign({}, str1);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }
為什麼字串會以陣列形式拷貝進入目標物件呢?
這是因為:只有字串的包裝物件,會產生可列舉屬性。
-- 數字不會拷入目標物件
const str2 = 123;
const obj = Object.assign({}, str2);
console.log(obj); // {}
-- 最後補充一點:
Object.assign()拷貝的屬性是有限制的,
只拷貝源物件的自身屬性(不拷貝繼承屬性),
也不拷貝不可列舉的屬性(enumerable: false)。
Object.assign()方法實行的是淺拷貝,而不是深拷貝。