一石景、對象屬性的簡潔寫法
1更舞、屬性簡寫
var foo = "bar";
var baz = { foo };
baz; // { foo: "baz" }
// 等價于
var baz = { foo: foo };
function f(x, y) {
return { x, y };
// 等價于: return { x: x, y: y };
}
f(1, 2); // {x: 1, y: 2}
2畦幢、方法簡寫
var obj = {
method() {
return "yuan is an animal";
}
}
// 等價于
var obj = {
method: function() {
return "yuan is an animal";
}
}
二、屬性名表達式
在ES5中缆蝉,定義對象的屬性有兩種方法
// 方法一:標識符作為屬性名
obj.foo = true;
// 方法二:表達式作為屬性名
obj["foo"] = true;
如果使用字面量方式定義對象宇葱,在ES5中只能使用方法一,而在ES6中可以使用方法二:
let yuan = "monkey";
let animal = {
"type": "animal",
[yuan]: "yuan is not monkey"
}
animal["type"]; // "animal"
animal[yuan]; // "yuan is not monkey"
animal["monkey"]; // "yuan is not monkey"
屬性名定義方法:
let monkey = {
['yuan']() {
return "yuan is a monkey";
}
}
monkey.yuan(); // yuan is a monkey"
三刊头、方法的name 屬性
對象中的方法黍瞧,也具有類似 function 的 name 屬性:
let monkey = {
['yuan']() {
return "yuan is a monkey";
}
}
monkey.yuan.name; // "yuan"
其他的用法同“ES6函數(shù)擴展”的 name 屬性用法類似。
四原杂、Object.is()
因在ES5中印颤,并不能處理比較兩個值是否嚴格相等,對于NaN穿肄,+0年局,-0等并不能做出嚴格相等來判斷际看。
Object.is() 這個方法就是來彌補上述的缺陷的:
+0 === -0; // true
NaN === NaN; // false
Object.is(+0, -0); // false
Object.is(NaN, NaN); // true
五、Object.assign()
1矢否、基本用法
定義:將源對象(sourceN仿村,不知一個源對象)的所有可枚舉屬性復(fù)制到目標對象上(target)。
使用方式:Object.assign(target, source1, source2, ..., sourceN)
let target = { x: 1};
let s1 = { y: 2 };
let s2 = { z: 3 };
Object.assign(target, s1, s2); // {x: 1, y: 2, z: 3}
2兴喂、注意點
(1)蔼囊、如果目標對象與源對象用同名屬性,或多個源對象具有同名屬性衣迷,則后面的屬性會覆蓋前面的屬性:
let target2 = { x: 1};
let s3 = { x: 3, y: 2 };
let s4 = { y: 4, z: 3 };
Object.assign(target2, s3, s4); // {x: 3, y: 4, z: 3}
(2)如果參數(shù)不是對象畏鼓,則會先轉(zhuǎn)成對象,在返回:
typeof Object.assign(3); // "object"
(3)壶谒、若參數(shù)中有undefined 或者 null云矫,這兩個參數(shù)不能放在目標對象的位置,否則會報錯:
Object.assign(undefined); // Cannot convert undefined or null to object at Function.assign (<anonymous>)
Object.assign(null); // Cannot convert undefined or null to object at Function.assign (<anonymous>)
(4)汗菜、除了字符串會以數(shù)組的形式復(fù)制到目標對象上让禀,其他值都不會產(chǎn)生效果:
let a1 = 'yuan';
let a2 = true;
let a3 = 11;
let a4 = NaN;
Object.assign({}, a1, a2, a3, a4); // {0: "y", 1: "u", 2: "a", 3: "n"}
(5)、Object.assign()這個方法是對對象引用的復(fù)制陨界,即是淺復(fù)制巡揍,而不是深復(fù)制。這里需要規(guī)避同名屬性替換帶來的問題:
var obj1 = { a: { b: 3, c: 4 } };
var obj2 = { a: { b: "yuan" } } ;
Object.assign(obj1, obj2); // { a: { b: "yuan" } }
obj1.a.b; // "yuan"
3菌瘪、基本用途
(1)腮敌、給對象添加屬性
class Geo {
constructor(x, y) {
Object.assign(this, x, y);
}
}
(2)、給對象添加方法
Object.assig(SomeClass.prototype, {
someMethod(arg1, arg2) { ... },
anotherMethod() { ... }
})
(3)俏扩、克隆對象
function clone(originObj) {
return Object.assign({}, originObj); // 將原始對象復(fù)制給空對象
}
(4)糜工、合并多個對象
const mergeObjs = {
(target, ...sources) => Object.assign(target, ...sources);
}
(5)、為屬性指定默認值
const DEFAULTS = {
logleve: 0,
outputFormat: 'html'
};
function processContent(options) {
retrun Object.assign({}, DEFAULTS, options);
}
六录淡、屬性的可枚舉性(Enumerable)
ES5 中有3個操作會忽略 Enumerable 為 false 的屬性:
1捌木、for...in 循環(huán):只遍歷對象自身的和繼承的可枚舉性。
2嫉戚、Object.keys():返回對象自身的所有可枚舉屬性的鍵名刨裆。
3、JSON.stringify():只串行化對象自身的可枚舉屬性彼水。
在ES6 中崔拥,Object.assign() 操作會忽略 Enumerable 為false 的屬性极舔。
在上面四個操作中凤覆,只有 for...in 操作會返回繼承的屬性,為了不使問題復(fù)雜化拆魏,只關(guān)心對象自身的屬性盯桦。所以慈俯,盡量不要使用 for...in 循環(huán),用 Object.keys() 代替拥峦。
ES6還規(guī)定贴膘,所有 Class 的原型的方法都是不可枚舉的。
七略号、屬性的遍歷
在ES6 中有五種方法來遍歷對象的屬性:
1刑峡、for...in
返回對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。
2玄柠、Object.keys(ob)
返回一個數(shù)組突梦,包括對象自身的(不含繼承)所有可枚舉屬性(不含 Symbol 屬性)。
3羽利、Object.getOwnPropertyNames(obj)
返回一個數(shù)組宫患,包括自身的所有屬性(不含Symbol屬性,但包括不可枚舉屬性)这弧。
4娃闲、Object.getOwnPropertySymbols(obj)
返回一個數(shù)組。包含對象自身的所有 Symbol 屬性匾浪。
5皇帮、Object.ownKeys(obj)
返回一個數(shù)組,包含對象所有的屬性.蛋辈。
以上五種方法都遵循同樣的遍歷順序:
(1)玲献、首先遍歷所有屬性名為數(shù)值的屬性,按數(shù)字排序梯浪;
(2)捌年、其次遍歷所有屬性名為字符串的屬性,按照生成時間排序挂洛;
(3)礼预、最后遍歷所有屬性名為 Symbol 的屬性,按照生成時間排序虏劲。
八托酸、Object.keys(),Object.values()柒巫,Object.entries()
1励堡、Object.keys(obj)
返回一個數(shù)組,是由參數(shù)對象自身的(不含繼承)所有可遍歷屬性的鍵名:
/* Array 對象 */
let arr = ["a", "b", "c"];
console.log(Object.keys(arr));
// ['0', '1', '2']
/* Object 對象 */
let obj = { foo: "bar", baz: 42 },
keys = Object.keys(obj);
// CCAC: Chrome Console Auto Copy
copy(keys);
// ["foo","baz"]
/* 類數(shù)組 對象 */
let obj = { 0 : "a", 1 : "b", 2 : "c"};
console.log(Object.keys(obj));
// ['0', '1', '2']
// 類數(shù)組 對象, 隨機 key 排序 (遵循上述的屬性的遍歷順序)
let anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj));
// ['2', '7', '100']
/* getFoo 是個不可枚舉的屬性 */
var my_obj = Object.create(
{},
{ getFoo : { value : function () { return this.foo } } }
);
my_obj.foo = 1;
console.log(Object.keys(my_obj));
// ['foo']
2堡掏、Object.values(obj)
返回一個數(shù)組应结,是由參數(shù)對象自身的(不含繼承)所有可遍歷屬性的鍵值:
var obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]
// 類數(shù)組對象
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']
// 隨機鍵值的類數(shù)組對象 (遵循上述的屬性的遍歷順序)
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']
// getFoo 是不可枚舉屬性
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = "bar";
console.log(Object.values(my_obj)); // ['bar']
// 參數(shù)是非對象會轉(zhuǎn)變成對象
console.log(Object.values("foo")); // ['f', 'o', 'o']
Object.values() 會過濾屬性名為 Symbol 值的屬性:
Object.values({ [Symbol() ]: 123, "foo": "faa"}) // ["faa"]
3、Object.entries(obj)
返回一個數(shù)組,是由參數(shù)對象自身的(不含繼承)所有可遍歷屬性的鍵值對數(shù)組:
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
// 類數(shù)組對象
const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
// 隨機鍵值的類數(shù)組對象 (遵循上述的屬性的遍歷順序)
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]
// getFoo 是不可枚舉屬性
const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
myObj.foo = 'bar';
console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ]
// 參數(shù)是非對象會轉(zhuǎn)變成對象
console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]
// 優(yōu)雅地遍歷鍵值
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}
Object.entries() 的另一個用處:將對象轉(zhuǎn)為真正的Map 數(shù)據(jù)結(jié)構(gòu):
var obj = { foo: "bar", baz: 42 };
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }
結(jié)語:
1鹅龄、本章重點在理解Object.keys()揩慕,Object.values(),Object.entries() 三個方法的使用以及Object.assign 的用法
2扮休、屬性在ES6中屬性的簡寫與屬性名的表達式
3迎卤、了解ES6中五種遍歷屬性的方法及其區(qū)別
章節(jié)目錄
1、ES6中啥是塊級作用域玷坠?運用在哪些地方蜗搔?
2、ES6中使用解構(gòu)賦值能帶給我們什么八堡?
3碍扔、ES6字符串?dāng)U展增加了哪些?
4秕重、ES6對正則做了哪些擴展不同?
5、ES6數(shù)值多了哪些擴展溶耘?
6二拐、ES6函數(shù)擴展(箭頭函數(shù))
7、ES6 數(shù)組給我們帶來哪些操作便利凳兵?
8百新、ES6 對象擴展
9、Symbol 數(shù)據(jù)類型在 ES6 中起什么作用庐扫?
10饭望、Map 和 Set 兩數(shù)據(jù)結(jié)構(gòu)在ES6的作用
11、ES6 中的Proxy 和 Reflect 到底是什么鬼形庭?
12铅辞、從 Promise 開始踏入異步操作之旅
13、ES6 迭代器(Iterator)和 for...of循環(huán)使用方法
14萨醒、ES6 異步進階第二步:Generator 函數(shù)
15斟珊、JavaScript 異步操作進階第三步:async 函數(shù)
16、ES6 構(gòu)造函數(shù)語法糖:class 類