深刻學習js系列是本身階段性成長的見證,但願經過文章的形式更加嚴謹、客觀地梳理js的相關知識,也但願可以幫助更多的前端開發的朋友解決問題,期待咱們的共同進步。前端
若是以爲本系列不錯,歡迎點贊、評論、轉發,您的支持就是我堅持的最大動力。數組
所謂的類數組對象:微信
擁有一個 length 屬性和若干索引屬性的對象閉包
舉個例子:app
var array = ['name','age','sex'];
var arrayLike ={
0: 'name',
1:'age',
2: 'sex',
length: 3
}
複製代碼
即使如此,爲何叫作類數組對象呢?函數
那讓咱們從讀寫、獲取長度、遍歷這三個方面看看這兩個對象:post
console.log(array.length); // 3
console.log(arrayLike.ength); // 3
複製代碼
for(var i = 0,len = array.length;i<len;i++){
……
}
for(var i = 0,len = arrayLike.length;i<len;i++){
……
}
複製代碼
是否是很像 那類數組對象可使用數組的方法嗎?好比:學習
arrayLike.push("4");
複製代碼
然而 上述代碼會報錯: arrayLike.push is not a function
測試
因此終歸仍是類數組,哈哈哈ui
若是類數組就是任性的想要使用數組的方法怎麼辦呢?
既然沒法直接的調用,咱們可使用 Function.call 間接調用:
var arrayLike ={ 0: 'name',1:'age',2: 'sex',length: 3 }
Array.prototype.join.call(arrayLike,'&'); // name&age&sex
Array.prototype.slice.call(arrayLike, 0); // ["name", "age", "sex"]
// slice能夠作到類數組轉數組
Array.prototype.map.call(arrayLike, function(item){
return item.toUpperCase();
});
// ["NAME", "AGE", "SEX"]
複製代碼
在上面的例子中已經提到了一種類數組轉數組的方法,再補充三個:
var arrayLike ={ 0: 'name',1:'age',2: 'sex',length: 3 }
// 1. slice
Array.prototype.slice.call(arrayLike); // ["name", "age", "sex"]
// 2. splice
Array.prototype.splice.call(arrayLike, 0); // ["name", "age", "sex"]
// 3. ES6 Array.from
Array.from(arrayLike); // ["name", "age", "sex"]
// 4. apply
Array.prototype.concat.apply([], arrayLike)
複製代碼
那麼爲何要講到類數組對象呢?以及類數組對象有什麼做用嗎?
要說到類數組對象,Arguments 對象就是一個類數組對象。在客戶端 JavaScript 這種,一些 DOM 方法
document.getElementsByTagName();
複製代碼
等也返回類數組對象。
接下來重點講講 Arguments 對象
Arguments 對象只定義在函數體中,包括了函數的參數和其餘屬性,在函數體中,arguments 指代該函數的 Arguments 對象
舉一個例子:
function foo(name, age, sex) {
console.log(arguments);
}
foo("name", "age", "sex");
複製代碼
打印結果以下:
咱們能夠看到除了類數組的索引屬性和 length 屬性以外,還有一個 callee 屬性,接下來咱們一個一個介紹。
length 屬性
Arguments 對象的 length 屬性,表示實參的長度,舉個例子:
function foo(b, c, d) {
console.log("實參的長度爲:" + arguments.length);
}
console.log("形參的長度爲:" + foo.length);
foo(1);
// 形參長度爲 3
// 實參的長度爲:1
複製代碼
Arguments 對象的 callee 屬性,經過它能夠調用函數自身。 講一個閉包經典米娜會題中使用 callee 的解決方法:
var data = [];
for (var i = 0; i < 3; i++) {
(data[i] = function() {
console.log(arguments.callee.i);
}).i = i;
}
data[0]();
data[1]();
data[2]();
// 0
// 1
// 2
複製代碼
接下來說講 arguments 對象的幾個注意要點:
function foo(name, age, sex, hobbit) {
console.log(name, arguments[0]); // name name
// 改變形參
name = "new name";
console.log(name, arguments[0]); // new name new name
// 改變arguments
arguments[1] = "new age";
console.log(age, arguments[1]); // new age new age
// 測試未傳入的是否會綁定
console.log(sex); // undefined
sex = "new sex";
console.log(sex, arguments[2]); // new sex undefined
arguments[3] = "new hobbit";
console.log(hobbit, arguments[3]); // undefined new hobbit
}
foo("name", "age");
複製代碼
傳入的參數,實參和 arguments 的值會共享,當沒有傳入時,實參與 arguments 值不會共享
除此以外,以上是在非嚴格模式下,若是是在嚴格模式下,實參和 arguments 是不會共享的。
將參數從一個函數傳遞到另一個函數
// 使用apply 將foo 的參數傳遞給bar
function foo() {
bar.apply(this, arguments);
}
function bar(a, b, c) {
console.log(a, b, c);
}
foo(1, 2, 3);
複製代碼
強大的 ES6
使用 ES6 的 ... 運算符,咱們能夠輕鬆的轉成數組
function func(...arguments) {
console.log(arguments); // [1,2,3]
}
func(1, 2, 3);
複製代碼
arguments的應用其實不少,若是要總結這些場景的話,暫時能想到的包括:
參數不定長 函數柯里化 遞歸調用 函數重載 ...
歡迎添加個人我的微信討論技術和個體成長。
歡迎關注個人我的微信公衆號——指尖的宇宙,更多優質思考乾貨