call
使用一個指定的上下文對象和若干個指定的參數值的前提下調用某個函數或方法。如果傳入null, 則this指向window
改變方法內部的this指向執行方法將函數設為對象的方法執行該方法刪除該方法Function.prototype.myCall =
function(context) {context.fn = this // this代表sayValue方法context.fn() // 執行sayValue方法delete context.fn // 刪除對象上的方法
}var obj = {value:
'hello javascript'
}
function sayValue() {console.log(this.value)
}sayValue.myCall(obj)
復制代碼通過函數的arguments對象,來獲取不定參數Function.prototype.myCall =
function (ctx) {ctx.fn = this// 將arguments轉化成數組,通過slice()方法截取數組除第一項以外的所有項,并返回截取的數組var newArr = Array.prototype.slice.call(arguments, 1)ctx.fn(...newArr) // ES6中的
'...' 展開運算符,可以展開數組delete ctx.fn
}
var obj = {value:
'hello, obj'
}
function saySth(name, age) {console.log(
'name: ', name)console.log(
'age: ', age)console.log(
'obj.value: ', this.value)
}saySth.myCall(obj,
'alex.cheng', 18)// 運行試試 !
復制代碼函數的返回值,看以下栗子:var obj = {}
obj.value =
'alex.cheng'
function bar() {
return {value: this.value}
}
bar.call(obj)>>> {value:
"alex.cheng"}
復制代碼最終實現Function.prototype.myCall =
function (ctx) {var ctx = ctx || window // 如果傳入的ctx是null的話,就將ctx指向windowctx.fn = this// 將arguments轉化成數組,通過slice()方法截取數組除第一項以外的所有項,并返回截取的數組var newArr = Array.prototype.slice.call(arguments, 1)var result = ctx.fn(...newArr) // ES6中的
'...' 展開運算符,可以展開數組delete ctx.fn
return result // 返回ctx.fn的返回值
}var value =
'hey, this is a global_value .' // 定義一個全局變量var obj = {value:
'hello, obj.value'
}
function saySth(name, age) {
return {name,age,value: this.value}
}saySth.myCall(obj,
'alex.cheng', 18) // 傳入obj,saySth函數的this指向obj
>>> {name:
"alex.cheng", age: 18, value:
"hello, obj.value"}saySth.myCall(null,
'alex.cheng', 18) // 傳入null,saySth函數的this指向window
{name:
"haolun", age: 18, value:
"hey, this is a global_value ."}// 自己動手試一試 @.@
復制代碼apply
apply的用法和call的用法一樣,唯一的區別,就是傳入的參數不同,apply需要傳入數組,例如 fn.apply( null, [ ] )
模擬實現也和call 相似,實現如下 :Function.prototype.myApply =
function (ctx) {var ctx = ctx || windowctx.fn = thisvar resultvar args = arguments[1] // 獲取傳入的數組
if (!args) { // 如果沒有傳入數組參數,則直接調用ctx.fn方法result = ctx.fn()}
else {result = ctx.fn(...args) // 如果傳入了數組參數,將數組參數采用ES6的
'...'擴展運算符將其展開并傳入ctx.fn方法}delete ctx.fn
return result
}// 親自試一試 :)
Math.max.myApply(null, [1,2,3,4,55,44,33,22,11])
復制代碼
總結
以上是生活随笔為你收集整理的javascript之模拟call以及apply实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。