這次帶給大家javascript中call與apply的應用,javascript中call與apply應用的注意事項有哪些,下面就是實戰案例,一起來看一下。
求陣列的最大值與最小值
定義一個陣列:
var ary = [23, 34, 24, 12, 35, 36, 14, 25];
排序再取值法
var ary = [23, 34, 24, 12, 35, 36, 14, 25]; ary.sort(function (a, b) { return a - b; });var min = ary[0];var max = ary[ary.length - 1]; console.log(min, max);1234567假設法假設目前數組中的第一個值是最大值,然後拿這個值和後面的項逐一進行比較,如果後面某一個值比假設的還要打,說明假設錯了,我們把假設的值進行替換…..
var max = ary[0], min = ary[0];for (var i = 1; i < ary.length; i++) { var cur = ary[i]; cur > max ? max = cur : null; cur < min ? min = cur : null; } console.log(min, max);1234567Math中的max/min方法實現(透過apply)直接使用Math.min
var min = Math.min(ary); console.log(min); // NaN console.log(Math.min(23, 34, 24, 12, 35, 36, 14, 25));直接使用Math.min的時候,需要把待比較的那堆數一個個的傳遞進去,這樣才可以得到最後的記過,一下放一個ary數組進去是不可以的。
var max = eval(“Math.max(” + ary.toString() + “)”); console.log(max); var min = eval(“Math.min(” + ary.toString() + “)”); console.log(min); “Math.max(” + ary.toString() + “)” –> “Math.max(23,34,24,12,35,36,14,25)”首先不要管其他的,先把我們最後要執行的程式碼都變成eval:把一個字串變成JavaScript表達式執行
例如:eval(“12+23+34+45”) // 114
var max = Math.max.apply(null, ary); var min = Math.min.apply(null, ary); console.log(min, max);在非嚴格模式下,給apply的第一個參數為null的時候,會讓max/min中的this指向window,然後將ary的參數一個個傳給max/min。
arguments.sort(); // Uncaught TypeError: arguments.sort is not a function
那麼這時候可不可以先將arguments轉換為一個真正的數組呢,然後再進行操作呢,按照這個思想,我們自己實現一個實現題目要求的業務方法:
function avgFn() { // 1、将类数组转换为数组:把arguments克隆一份一模一样的数组出来 var ary = []; for (var i = 0; i < arguments.length; i++) { ary[ary.length] = arguments[i]; } // 2、给数组排序,去掉开头和结尾,剩下的求平均数 ary.sort(function (a, b) { return a - b; }); ary.shift(); ary.pop(); return (eval(ary.join('+')) / ary.length).toFixed(2); }var res = avgFn(9.8, 9.7, 10, 9.9, 9.0, 9.8, 3.0); console.log(res);1234567891011121314151617我們發現在自己實現的avgFn方法中有一個步驟為將arguments克隆出來生成是一個數組。如果對數組的slice方法比較熟悉的話,可以知道當slice方法什麼參數都不傳的時候就是克隆當前的數組,可以模擬為:
function mySlice () { // this->当前要操作的这个数组ary var ary = []; for (var i = 0; i < this.length; i++) { ary[ary.length] = this[i]; } return ary; };var ary = [12, 23, 34];var newAry = mySlice(ary); console.log(newAry);1234567891011所以在avgFn方法中的將arguments轉換為數組的操作可以透過call方法來借用Array中的slice方法。
function avgFn() { // 1、将类数组转换为数组:把arguments克隆一份一模一样的数组出来 // var ary = Array.prototype.slice.call(arguments); var ary = [].slice.call(arguments); // 2、给数组排序,去掉开头和结尾,剩下的求平均数....123 }我們現在的做法是先將arguments轉換為數組,然後再操作轉換之後的數組,那麼可以不可以直接就用arguments而不要先轉換為數組呢? 當然是可以的,透過call來借用數組的方法來實現。
function avgFn() { Array.prototype.sort.call(arguments , function (a, b) { return a - b; }); [].shift.call(arguments); [].pop.call(arguments); return (eval([].join.call(arguments, '+')) / arguments.length).toFixed(2); }var res = avgFn(9.8, 9.7, 10, 9.9, 9.0, 9.8, 3.0); console.log(res);123456789101112將類別數組轉換數組在之前提到了借用數組的slice方法將類別數組物件轉換為數組,那麼透過
getElementsByTagName等方法獲取的類別數組物件是不是也可以藉用slice方法來轉換成陣列物件呢?
var oLis = document.getElementsByTagName('div');var ary = Array.prototype.slice.call(oLis);
console.log(ary);
#在標準瀏覽器下,的確可以這麼用,但在IE6~8下就悲劇了,會報錯:
#那麼在IE6~8下就只能透過循環一個個加到數組中了:
for (var i = 0; i < oLis.length; i++) { ary[ary.length] = oLis[i]; }注意:對於arguments借用數組的方法是不存在任何相容性問題的。
function listToArray(likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i < likeAry.length; i++) { ary[ary.length] = likeAry[i]; } } return ary; }1234567891011這個工具方法中用到了瀏覽器的異常資訊捕獲,那麼這裡也介紹一下吧。 console.log(num);
當我們輸出一個沒有定義的變數的時候會報錯:Uncaught ReferenceError: num is not defined,在JavaScript中,本行報錯,下面的程式碼都不再執行了。
console.log(num); } catch (e) { // 形参必须要写,我们一般起名为e console.log(e.message); // –> num is not defined 可以收集当前代码报错的原因 } console.log(‘ok’);所以try…catch的使用格式為(和Java中很像):
try { // } catch (e) { // 如果代码报错执行catch中的代码 } finally { // 一般不用:不管try中的代码是否报错,都要执行finally中的代码 }這個時候既想捕獲到信息,又不想讓下面的diamante執行,那麼該怎麼做呢?
try { console.log(num); } catch (e) { // console.log(e.message); // --> 可以得到错误信息,把其进行统计 // 手动抛出一条错误信息,终止代码执行 throw new Error('当前网络繁忙,请稍后再试'); // new ReferenceError --> 引用错误 // new TypeError --> 类型错误 // new RangeError --> 范围错误 }console.log('ok');我相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章! 推薦閱讀:
javascript中call與apply以及bind有哪些不同
#
以上是javascript中call與apply的應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!