摘要:在客戶端中,一些方法等也返回類數組對象。對象接下來重點講講對象。在函數體中,指代該函數的對象。下一篇文章深入之創建對象的多種方式以及優缺點深入系列深入系列目錄地址。
類數組對象JavaScript深入系列第十三篇,講解類數組對象與對象的相似與差異以及arguments的注意要點
所謂的類數組對象:
擁有一個 length 屬性和若干索引屬性的對象
舉個例子:
var array = ["name", "age", "sex"]; var arrayLike = { 0: "name", 1: "age", 2: "sex", length: 3 }
即便如此,為什么叫做類數組對象呢?
那讓我們從讀寫、獲取長度、遍歷三個方面看看這兩個對象。
讀寫console.log(array[0]); // name console.log(arrayLike[0]); // name array[0] = "new name"; arrayLike[0] = "new name";長度
console.log(array.length); // 3 console.log(arrayLike.length); // 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
所以終歸還是類數組吶……
調用數組方法如果類數組就是任性的想用數組的方法怎么辦呢?
既然無法直接調用,我們可以用 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 指代該函數的 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 // 實參的長度為:1callee屬性
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 對象的幾個注意要點:
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的應用其實很多,在下個系列,也就是 JavaScript 專題系列中,我們會在 jQuery 的 extend 實現、函數柯里化、遞歸等場景看見 arguments 的身影。這篇文章就不具體展開了。
如果要總結這些場景的話,暫時能想到的包括:
參數不定長
函數柯里化
遞歸調用
函數重載
...
歡迎留言回復。
下一篇文章JavaScript深入之創建對象的多種方式以及優缺點
深入系列JavaScript深入系列目錄地址:https://github.com/mqyqingfeng/Blog。
JavaScript深入系列預計寫十五篇左右,旨在幫大家捋順JavaScript底層知識,重點講解如原型、作用域、執行上下文、變量對象、this、閉包、按值傳遞、call、apply、bind、new、繼承等難點概念。
如果有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。如果喜歡或者有所啟發,歡迎star,對作者也是一種鼓勵。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82908.html
摘要:深入系列第十二篇,通過的模擬實現,帶大家揭開使用獲得構造函數實例的真相一句話介紹運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象類型之一也許有點難懂,我們在模擬之前,先看看實現了哪些功能。 JavaScript深入系列第十二篇,通過new的模擬實現,帶大家揭開使用new獲得構造函數實例的真相 new 一句話介紹 new: new 運算符創建一個用戶定義的對象類型的實例或具...
摘要:寫在前面深入系列共計篇已經正式完結,這是一個旨在幫助大家,其實也是幫助自己捋順底層知識的系列。深入系列自月日發布第一篇文章,到月日發布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 深入系列共計 15 篇已經正式完結,這是一個旨在幫助大家,其實也是幫助自己捋順 JavaScript 底層知識的系列。重點講解了如原型、作用域、執行上下文、變量對象、this、...
摘要:但是,我們可以借用類數組方法不難看出,此時的在調用數組原型方法時,返回值已經轉化成數組了。很多時候,深入看看源代碼也會讓你對這個理解的更透徹。的前端樂園原文鏈接深入理解類數組 起因 寫這篇博客的起因,是我在知乎上回答一個問題時,說自己在學前端時把《JavaScript高級程序設計》看了好幾遍。于是在評論區中,出現了如下的對話:showImg(https://segmentfault.c...
摘要:的作用在中,方法和方法都是為了改變函數運行時上下文而存在的,換句話說就是為了改變函數體內部的指向。歡迎前端大牛糾正錯誤,如有錯誤我會及時改正。 寫在前面: 隔了很長時間了,也不知道寫點什么。最近一直在研究ES6,一直想寫出來的文章能對初學者或者是在學習JS路上有所幫助的。這就是我的初衷。 call、apply的作用 在JavaScript中,call()方法和apply()方法都是為了...
摘要:剛開始看到的函數和時,非常的模糊,不知所云,然后看書,網上查詢多少知道點了眉目,下面是我做的筆記,希望和大家分享,有不對之處希望各位多多指正,共同進步。。。 剛開始看到javascript的函數apply和call時,非常的模糊,不知所云,然后看書,網上查詢多少知道點了眉目,下面是我做的筆記,希望和大家分享,有不對之處希望各位多多指正,共同進步。。。本文將從三個方面介紹apply,ca...
閱讀 2080·2021-11-24 10:34
閱讀 3055·2021-11-22 11:58
閱讀 3712·2021-09-28 09:35
閱讀 1724·2019-08-30 15:53
閱讀 2770·2019-08-30 14:11
閱讀 1551·2019-08-29 17:31
閱讀 542·2019-08-26 13:53
閱讀 2141·2019-08-26 13:45