1. 程式人生 > 其它 >重寫Function.prototype.call()方法

重寫Function.prototype.call()方法

技術標籤:JavaScriptJS面試javascriptjs

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body
>
<script> /* * 1. apply 可以執行函式 * 2. apply的第二個引數是一個數組,也是實參列表 * 3. apply的第二個引數如果為物件或者函式,arguments.length 為 0(不報錯) * 4. apply只、取到第二個引數, 第三個到最後一個引數會被忽略 * 5. apply的第二個引數傳遞 null/undefined 不報錯, arguments.length 為 0 * 6. apply的第二個引數如果為原始值(string、number、boolean)會報錯: * Uncaught TypeError: CreateListFromArrayLike called on non-object */
// array object function typeOf(value) { if (value === null) { return 'null' } // ({}).toString.call(value) -> [object Object] return typeof(value) === 'object' ? { '[object Object]': 'Object', '[object Array]': 'Array', '[object Number]': 'Number', '[object String]'
: 'String', '[object Boolean]': 'Boolean' }[({}).toString.call(value)] : typeof(value) } Function.prototype.myApply = function(context, args) { context = Object(context) || window context.originFn = this // 如果傳入的引數為原始值型別並且不為function,報錯 if (typeof(args) !== 'object' && typeof(args) !== 'function') { throw new TypeError('Uncaught TypeError: CreateListFromArrayLike called on non-object') } // 如果沒有傳入第二個引數, 直接執行函式 if (!args || typeOf(args) !== 'Array') { return context.originFn() } // 執行函式 // ' + args + ': 可以將實引數組平鋪 var ret = eval('context.originFn(' + args + ')') // 刪除屬性 delete context.originFn // 返回函式的執行結果 return ret } // 測試重寫後的效果 function test() { console.log(this, arguments) } test.apply({ a: 1, b: 2 }, [3, 4, 5])
</script> </body> </html>

在這裡插入圖片描述