萬物皆物件
1、Object.assign()
Object.assign(target, source);將source物件中所有可列舉的屬性的值複製到目標物件中,其會返回目標物件。
相容方法:
if(typeof Object.assign!='function'){
Object.assign = function(target){
'use strict';
if(target = null){
throw new TypeError('Cannot convert undefined or null to object');
}
target = Object(target);
for(var index=0;index
}
}
複製程式碼
Object.assign()只是對一級屬性進行復制,而不會對物件中的物件再進行深度拷貝。如果出現同名的屬性值,後者的值會覆蓋前者。
- 用在為物件新增屬性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
複製程式碼
上面方法通過 assign 方法,將 x 屬性和 y 屬性新增到 Point 類的物件例項
2)為物件新增方法
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});
// 等同於下面的寫法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};
複製程式碼
3)合併多個物件到一個新物件
const merge =
(...sources) => Object.assign({}, ...sources);
複製程式碼
4)為屬性指定預設值
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
let options = Object.assign({}, DEFAULTS, options);
}
複製程式碼
2、Obejct.is()
Object.is()用來比較兩個值是否嚴格相等。它與嚴格比較運算子的作用基本相等,不同之處只有兩個,一是 +0 不等於 -0,二是 NaN 等於自身。
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
複製程式碼
ES5可以用下面的辦法,部署Object.is()
Object.defineProperty(Object, 'is', {
value: function(x, y) {
if (x === y) {
// 針對+0 不等於 -0的情況
return x !== 0 || 1 / x === 1 / y;
}
// 針對NaN的情況
return x !== x && y !== y;
},
configurable: true,
enumerable: false,
writable: true
});
複製程式碼
3、Object.defineProperty()
Object.defineProperty()直接在一個物件上定義一個新屬性,或者修改一個已經存在的屬性,並且返回這個物件。
// 給obj物件定義了一個屬性key,其不可列舉,不可配置,只讀,值為static。
Object.defineProperty(obj, "key", {
enumerable: false, // 當且僅當該屬性出現在相應的物件列舉屬性中。預設為 false。
configurable: false, // 當且僅當這個屬性描述符值為 true 時,該屬性可能會改變,也可能會被從相應的物件刪除。預設為 false。
writable: false, // 定義屬性值是否可寫。
value: "static" // 屬性的值
});
複製程式碼
4、Object.defineProperties()
Object.defineProperties(obj,props)為物件定義屬性。 方法直接在一個物件上修改或建立屬性,並返回修改後的物件。
5、Object.create()
Object.create() 方法建立一個擁有指定原型和若干個指定屬性的物件。
// 建立一個繼承自Object.prototype的物件,有一個屬性a,其可寫,可配置,不可列舉,值為1。
Object.create(Object.prototype, {
a: {
value: 1,
writable: true,
configurable: true
}
});
複製程式碼
6、Object.keys
Object.keys() 方法會返回一個由給定物件的所有可列舉自身屬性的屬性名組成的陣列,陣列中屬性名的排列順序和使用for-in迴圈遍歷該物件時返回的順序一致(兩者的主要區別是 for-in 還會遍歷出一個物件從其原型鏈上繼承到的可列舉屬性)。
var obj = {a: 1, b: 2};
console.log(Object.keys(obj));
// > ["a", "b"]
複製程式碼
keys可以用來代替原來的for in迴圈,藉助es5新增的陣列方法,可提升程式碼可讀性。
Object.keys(obj).forEach(function (val) {console.log(val)});
複製程式碼
7、Object.freeze
Object.freeze() 方法可以凍結一個物件。凍結物件是指那些不能新增新的屬性,不能修改已有屬性的值,不能刪除已有屬性,以及不能修改已有屬性的可列舉性、可配置性、可寫性的物件。也就是說,這個物件永遠是不可變的。該方法返回被凍結的物件。
Object.freeze(obj)
複製程式碼
凍結物件是不可擴充套件的,密封的,同時期值屬性的writable會被設定為false,set也將失效,總之會變為不可更改。任何嘗試修改該物件的操作都會失敗,可能是靜默失敗,也可能會丟擲異常(嚴格模式)。
8、Object.values()
Object.values方法返回一個陣列,成員是引數物件自身的(不含繼承的)所有可遍歷( enumerable )屬性的鍵值。
var obj = { foo: "bar", baz: 42 };
Object.values(obj)
// ["bar", 42]
複製程式碼
9、Object.entries
Object.entries方法返回一個陣列,成員是引數物件自身的(不含繼承的)所有可遍歷( enumerable )屬性的鍵值對陣列。
var obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]
複製程式碼
10、Object.hasOwnProperty()
Object.hasOwnProperty() 方法用來判斷某個物件是否含有指定的自身屬性。
obj.hasOwnProperty(prop)
複製程式碼
在沒有Object.keys之前,藉助hasOwnProperty,可以讓for in 達到類似的效果
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
//過濾掉原型上的方法
}
}
複製程式碼
陣列物件的作用是:使用單獨的變數名來儲存一系列的值。
1、Array.from()
Array.from()將類陣列物件轉換成一個真正的陣列
let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 }
console.log(Array.from(arrayLike)); // ["a","b","c"]
複製程式碼
2、Array.concat()
Array.concat()進行陣列合並
let arr = [1, 2, 3]
arr.concat([4, 5]) // [1, 2, 3, 4, 5]
複製程式碼
3、Array.sort()
Array.sort()進行陣列排序
arr.sort(); // 升序,預設
arr.sort((a, b) => a - b); // 升序
arr.sort((a, b) => b - a); // 降序
複製程式碼
4、fill, sort, reverse, copyWithin, splice
var arr = [3, 6, 5, 8, 5];
// 測試時arr原始值都是[3, 6, 5, 8, 5],以下操作都會改變arr
arr.fill(0, 1, 3); // [3, 0, 0, 8, 5],array.fill(value, start?, end?)
new Array(10).fill(0); // 新陣列填充非常方便
['a', 'c', 'b', 'd'].sort().reverse(); // 字串陣列的降序
arr.copyWithin(2, 1, 2); // [3, 6, 6, 5, 5],array.copyWithin(target, start, end?)
arr.copyWithin(2, 1); // [3, 6, 6, 5, 8],end預設為length-1
// 返回值是被刪除的元素,array.splice(index, howmany?, item?...)
arr.splice(1); // 返回[6, 5, 8, 5], arr = [3]
arr.splice(1, 2); // 返回[6, 5], arr = [3, 8, 5]
arr.splice(1, 2, 0); // 返回[6, 5], arr = [3, 0, 8, 5]
複製程式碼
5、indexOf, lastIndexOf, includes, find, findIndex, some, every
var arr = [3, 6, 5, 8, 5];
arr.indexOf(5, 3); // 4, array.indexOF(value, start?),和String物件原理相同
arr.lastIndexOf(5, 3); // 2,無匹配返回-1
arr.includes(5, -2); // true,這裡相當於length+(-2)
// 以下方法的引數都是:(function(curValue, index, array){}, thisValue)
arr.find(num => num > 5); // 6,第一個大於5的element,無匹配返回undefined
arr.findIndex(num => num > 5); // 2,第一個大於5的element的index,無匹配返回-1
arr.some(num => num > 5); // true,有element > 5
arr.every(num => num > 5); // false,不是所有element > 5
arr.findIndex((num, index, array) => index > 2 && num > 5) // 等價於indexOf(5, 3)
複製程式碼
6、slice, filter, map, forEach, reduce, reduceRight
var arr = [3, 6, 5, 8, 5];
arr.slice(1, -2); // [6, 5],原理同String物件
// 以下方法的引數都是:(function(curValue, index, array){}, thisValue)
arr.filter(num => num > 5); // [6, 8]
arr.map(num => num * 2); // [6, 12, 10, 16, 10]
// 注意:輸出6行,最後為undefined
arr.forEach((num, index) => {
console.log(index > 2 && num > 5 ? num : 0);
})
// 引數:(function(total, curValue, index, array){}, initialValue)
arr.reduce((total, num) => total + num); // 27,所有值相加
arr.reduceRight(((total, num) => total - num), 100); // 73,從右開始,100-elementValue
複製程式碼
7、keys, values, entries
// 都返回遍歷器(Iterator)物件,其他語言有叫遊標(cursor)的
for (let index of ['a', 'b'].keys()) {
console.log(index); // 0, 1
}
// 報錯:TypeError: ["a","b"].values(...) is not iterable,但看阮一峰的測試是可以的
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
let arr = ['a', 'b'];
let entries = arr.entries(); // entries={},Iterator物件
entries.next(); // {value: [0, 'a'], done: false}
entries.next(); // {value: [1, 'b'], done: false}
entries.next(); // {value: undefined, done: true},判斷是否遍歷完畢
複製程式碼
8、擴充套件運算子(…)
// 將Array展開成逗號分隔的引數序列,主要用於函式呼叫
console.log(1, ...[2, 3, 4], 5); // 1 2 3 4 5
// 替代apply方法
let arr = [0, 1, 2];
Math.max.apply(null, arr); // 2
Math.max(...arr); // 2
Array.prototype.push.apply(arr, [3, 4, 5]);
arr.push(...[3, 4, 5]);
new (Date.bind.apply(Date, [null, 2018, 7, 1]));
new Date(...[2018, 7, 1]);
複製程式碼
9、from, of
// 部署了Iterator介面的資料結構,會呼叫Iterator轉為Array
Array.from('test'); // ['t', 'e', 's', 't']
Array.from(new Set(['a', 'b'])); // ['a', 'b']
// 有length屬性的資料結構
let obj = {}
Array.from(obj) // [],空陣列
obj.length = 3
Array.from(obj) // [undefined, undefined, undefined]
let obj = {'3': 3, '2': 2, '1': 1}
obj.length = 4 // [undefined, 1, 2, 3],下標會排序,沒有找到'0'屬性
obj.length = 3 // [undefined, 1, 2],'3'被捨去了
// 將一組值轉換為Array
Array.of(); // []
Array.of(undefined); // [undefined]
Array.of(1); // [1]
Array.of(1, 2, 3); // [1, 2, 3]
複製程式碼
參考: