1. 屬性的簡介表示法
var foo = 'bar';
var baz = {foo};
baz //{foo: "bar"}
//等同于
var baz = {foo: foo};
var obj = {
class() {}
};
//等同于
var obj = {
‘class’: function() {}
}
ES6允許在對象之中憔杨,只寫屬性名匆赃,不寫屬性值淤毛。此時,屬性值等于屬性名所代表的變量炸庞。如果某方法的值是一個Generator函數(shù)钱床,函數(shù)名前面需要加上星號。
2. 屬性名表達式
- JavaScript語言定義對象的屬性有兩種方法埠居。
//方法一
obj.foo = true;
//方法二
obj['a' + 'bc'] = 123;
上述中查牌,方法一是直接用標識符作為屬性名事期。方法二是用表達式作為屬性名,這時要將表達式放在方括號之中纸颜。
- ES6允許字面量定義對象時兽泣,用方法二(表達式)作為對象的屬性名,即把表達式放在方括號內(nèi)胁孙。
let propkey = 'foo';
let obj = {
[propkey]: true;
['a' + 'bc']: 123
}
//例子二
var lastWord = 'last word';
var a = {
'first word': 'hello',
[lastWord]: 'world'
}
a['first word'] //"hello"
a[lastWord] //"world"
a['last word'] //"world"
注意:屬性名表達式與簡介表示法唠倦,不能同時使用,會報錯涮较。
//報錯
var foo = 'bar';
var bar = 'abc';
var baz = {[foo]};
//正確
var foo = 'bar';
var baz = {[fool]: 'abc'};
3. 方法的name屬性
- 函數(shù)的name屬性稠鼻,返回函數(shù)名。對象方法也有name屬性狂票。
var person = {
sayName() {
console.log(this.name);
},
get firstName() {
return "Nicholas";
}
};
person.sayName.name //"sayName"
person.firstName.name //"get firstName"
方法的name屬性返回函數(shù)名候齿。如果使用了取值函數(shù),則會在方法名前加上get闺属。如果是存值函數(shù)慌盯,則加上set。
- 有兩種特殊情況:
- bind方法創(chuàng)造的函數(shù)掂器,name屬性返回“bound”加上原函數(shù)的名字亚皂;
- Function構造函數(shù)創(chuàng)造的函數(shù),name屬性返回“anonymous”
(new Function()).name //"anonymous"
var doSomething = function() {}
doSomething.bind().name //"bound doSomething
- 如果對象的方法是一個Symbol值国瓮,name屬性返回的是這個Symbol值得描述灭必。
const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
[key1]() {},
[key2]() {}
};
obj[key1].name //"description"
obj[key2].name //""
4. Object.is()
- ES6提出了同值相等算法,用來比較兩個值是否嚴格相等巍膘,與嚴格比較運算符(===)的行為基本一致厂财。
Object.is('foo', 'foo') //true
Object.is({}, {}) //false
- 與===不同之處:
+0 === -0 //true
NaN === NaN //false
Object.is(+0,-0) //false
Object.is(NaN,NaN) //true
5. Object.assign()
基本用法
- 該方法用于對象的合并,將源對象的所有可枚舉屬性峡懈,賦值到目標對象。第一個參數(shù)是目標對象与斤,后面的參數(shù)都是源對象肪康。
如果目標對象與源對象有同名屬性,或多個源對象有同名屬性撩穿。則后面的覆蓋前面的屬性磷支。
- 如果只有一個參數(shù),則會直接返回該參數(shù)食寡。
- 如果只有一個參數(shù)雾狈,其參數(shù)不是對象,則先轉(zhuǎn)成對象抵皱,然后返回善榛。
- 由于undefined和null無法轉(zhuǎn)為對象辩蛋,所以它們作為參數(shù)時報錯。
- 如果非對象參數(shù)出現(xiàn)在源對象的位置移盆,如果該參數(shù)無法轉(zhuǎn)為對象悼院,則跳過。不報錯咒循。
- 其他類型的值(即數(shù)值据途、字符串和布爾值)不在首參數(shù),不會報錯叙甸。但是颖医,除了字符串會以數(shù)組形式拷貝入目標對象,其他值都不會產(chǎn)生效果裆蒸。
- 屬性名為Symbol的屬性便脊,也會被Object.assign拷貝。
注意點
- 該方法是淺拷貝光戈。如果源對象某個屬性的值是對象哪痰,則目標對象拷貝得到的是這個對象的引用。
- 對于嵌套的對象久妆,遇到同名屬性晌杰,替換而不添加。
- 該方法把數(shù)組視為對象筷弦。即相同index的值會被替換肋演。
6. 屬性的可枚舉性
- Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述對象。
- enumerable屬性稱為“可枚舉性”烂琴,如果為false爹殊,表示某些操作會忽略當前屬性。會忽略它為false的屬性:
- for...in循環(huán):只遍歷對象自身的和繼承的可枚舉的屬性(不含Symbol屬性)奸绷。
- Object.keys():返回對象自身的所有可枚舉的屬性的鍵名(不含Symbol屬性)梗夸。
- JSON.stringify():只串行化對象自身的可枚舉的屬性。
- Object.assign():只拷貝對象自身的可枚舉的屬性号醉。
7. 屬性的遍歷
- for...in:同上
- Object.keys(obj):同上
- Object.getOwnPropertyNames(obj):返回一個數(shù)組反症,包含對象自身的所有屬性(不含Symbol屬性,但是包括不可枚舉屬性)畔派。
- Object.getOwnPropertySymbols(obj):Object.getOwnPropertySymbols
返回一個數(shù)組铅碍,包含對象自身的所有Symbol屬性。 - Reflect.ownKeys(obj):Reflect.ownKeys
返回一個數(shù)組线椰,包含對象自身的所有屬性胞谈,不管是屬性名是Symbol或字符串,也不管是否可枚舉。
- 以上的5種方法遍歷對象的屬性烦绳,都遵守同樣的屬性遍歷的次序規(guī)則卿捎。
- 首先遍歷所有屬性名為數(shù)值的屬性,按照數(shù)字排序爵嗅。
- 其次遍歷所有屬性名為字符串的屬性娇澎,按照生成時間排序。
- 最后遍歷所有屬性名為Symbol值的屬性睹晒,按照生成時間排序趟庄。
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]
8. __proto__屬性,Object.setPrototypeOf(),Object.getPrototypeOf()
- __proto__屬性
- 前后各有兩個下劃線伪很,用來讀取或設置當前對象的prototype對象戚啥。
- 實際上,__proto__調(diào)用的是object.prototype.__proto__
- Object.setPrototypeOf()
- 與上一個作用相同锉试,設置一個對象的prototype對象猫十。
- Object.values(),Object.entries()
- Object.keys():返回一個數(shù)組,成員是參數(shù)對象自身(不含繼承)的所有可遍歷屬性的鍵名呆盖。
- Object.values()返回一個數(shù)組拖云,成員是參數(shù)對象自身(不含繼承)的所有可遍歷屬性的鍵值。順序與屬性的遍歷順序一致(上)
- 該方法會過濾屬性名為Symbol的屬性应又。
- 如果參數(shù)是一個字符串宙项,返回各個字符組成的數(shù)組。
- 參數(shù)是數(shù)值或布爾值株扛,返回空值尤筐。
- Object.entries
- 返回一個數(shù)組,成員是參數(shù)對象自身(不含繼承)的所有可遍歷屬性的鍵值對數(shù)組洞就。
- 除了返回值不同盆繁,方法的行為同上。
- 可以將對象轉(zhuǎn)為真正的Map結(jié)構旬蟋。
var obj = { foo: 'bar', baz: 42 };
var map = new Map(Object.entries(obj));
map // Map { foo: "bar", baz: 42 }
10. 對象的擴展運算符
解構賦值
-
等號右邊為對象油昂。是null或undefined時報錯。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }let { x, y, ...z } = null; // 運行時錯誤 let { x, y, ...z } = undefined; // 運行時錯誤
解構賦值必須是最后一個參數(shù)咖为,否則報錯秕狰。
解構賦值的拷貝是淺拷貝。如果一個鍵的值是復合類型的值躁染,則拷貝的是這個值的引用。
解構賦值不會拷貝繼承自原型對象的屬性架忌。
擴展運算符
(...)用于去除參數(shù)對象的所有可遍歷屬性吞彤,拷貝到當前對象之中。等同于Object.assign方法。
可以用于合并兩個對象饰恕。
let ab = {...a, ...b};
//等同于
let ab = Object.assign({},a,b);自定義的屬性放在擴展運算符后面挠羔,則擴展運算符內(nèi)部的同名屬性會被覆蓋掉。