對象
() -> 裡面只能是表達式,可以避免聲明對象或是代碼塊的歧異
({ foo: 123 }) // 正确
({ console.log(123) }) // 报错
鍵值會自動轉成string
可以用. 或是[]來訪問屬性
獲取對象的屬性
object.keys(obj)
返回由obj的keys組成的數組
delete
只有delete不能刪除的屬性才會返回false
刪除存在的屬性 -> true
刪除不存在的屬性 -> true
刪除繼承的屬性 -> true (實際沒有刪除)
不能刪除的屬性可以用Object.defineProperty
聲明
判斷屬性是否存在
'keys' in obj
繼承來的也會返回true ,可以配合hasOwnProperty來確認是否是自己的屬性
for in 循環
會返回所有的可以遍歷的keys(包含繼承來的)
with
可以用
with(obj) {
p = a;
}
直接訪問obj中的屬性,缺點是with沒有改變作用域,如果中間對obj沒有的屬性進行賦值,會得到一個新的全局變量
var obj = {};
with (obj) {
p1 = 4;
p2 = 5;
}
obj.p1 // undefined
p1 // 4
不能新增新的屬性
數組
數組的本質也是對象
typeof [1, 2, 3] // "object"
keys就是index
var arr = ['a', 'b', 'c'];
Object.keys(arr)
// ["0", "1", "2"]
length属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员数量会自动减少到length设置的值。
var arr = [ 'a', 'b', 'c' ];
arr.length // 3
arr.length = 2;
arr // ["a", "b"]
可以用來清空數組arr.length = 0
可以像對象那樣給數組添加屬性,但是不會改變數組的長度
var a = [];
a['p'] = 'abc';
a.length // 0
a[2.1] = 'abc';
a.length // 0
a // [p: 'abc', 2.1: 'abc']
對象沒有length屬性
數組有限定的大小,JavaScript使用32位整數來保存數組元素的個數,所以最多有4294967295(2^32 - 1)個成員
如果超過這個大小,會自動把鍵名轉為字符串
var arr = [];
arr[-1] = 'a';
arr[Math.pow(2, 32)] = 'b';
arr.length // 0
arr[-1] // "a"
arr[4294967296] // "b"
數組的鍵名都會轉成字符串
a[0] = 1 // 相等
a['0'] = 1
個人理解:
數組可以分為兩部分
- 在有效數字範圍0~4294967294,會被計算在數組的長度中
- 其餘可以使用arr[key]進行新增,但是不會被添入數組中
兩部分都可以使用for in遍歷
in 運算符
檢查keys 是否 in Arr
var arr = [ 'a', 'b', 'c' ];
2 in arr // true
'2' in arr // true
4 in arr // false
如果某位為空,也會返回false
var arr = [];
arr[100] = 'a';
100 in arr // true
1 in arr // false
空位
arr = [, 1]
0是一個空位
也可以用delete製造空位
直接讀取空位會返回undefined,但是不會影響數組長度
var a = [1, 2, 3];
delete a[1];
a[1] // undefined
a.length // 3
空位在遍歷中會被跳過
var a = [, , , 9];
a.forEach(function (x, i) {
console.log(i + '. ' + x);
})
// 3.9
for (var i in a) {
console.log(i);
}
// 3
Object.keys(a)
// ['3']
undefined不會被跳過
var a = [undefined, undefined, undefined];
a.forEach(function (x, i) {
console.log(i + '. ' + x);
});
// 0. undefined
// 1. undefined
// 2. undefined
for (var i in a) {
console.log(i);
}
// 0
// 1
// 2
Object.keys(a)
// ['0', '1', '2']
類似數組的對象
鍵名都是數字,並且有length屬性(主要)
可以使用數組判斷方式判別
'abc' instanceof Array // false
把類似數組的對象轉成數組:var arr = Array.prototype.slice.call(arrayLike);
也可以用call把數組的方法放到對象上
function print(value, index) {
console.log(index + ' : ' + value);
}
Array.prototype.forEach.call(arrayLike, print); // 從Array的原型中調取forEach方法,將this指向arrayLike,print作為參數
這樣會比直接使用forEach慢,先轉換成數組再調用方法會好一點
為什麼可以用slice轉成數組呢
根據MDN對slice的解釋
slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。
重點在於複製了原數組中的元素,返回新的數組
對於非數組的類數組對象,使用slice可以很方便地將其轉換成數組 -> 取出元素,轉成數組