生活随笔
收集整理的這篇文章主要介紹了
javascript之模拟call以及apply实现
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
call
使用一個(gè)指定的上下文對(duì)象和若干個(gè)指定的參數(shù)值的前提下調(diào)用某個(gè)函數(shù)或方法。如果傳入null, 則this指向window
改變方法內(nèi)部的this指向執(zhí)行方法將函數(shù)設(shè)為對(duì)象的方法執(zhí)行該方法刪除該方法Function.prototype.myCall =
function(context) {context.fn = this // this代表sayValue方法context.fn() // 執(zhí)行sayValue方法delete context.fn // 刪除對(duì)象上的方法
}var obj = {value:
'hello javascript'
}
function sayValue() {console.log(this.value)
}sayValue.myCall(obj)
復(fù)制代碼-
實(shí)現(xiàn)步驟二 (傳入?yún)?shù))
通過(guò)函數(shù)的arguments對(duì)象,來(lái)獲取不定參數(shù)Function.prototype.myCall =
function (ctx) {ctx.fn = this// 將arguments轉(zhuǎn)化成數(shù)組,通過(guò)slice()方法截取數(shù)組除第一項(xiàng)以外的所有項(xiàng),并返回截取的數(shù)組var newArr = Array.prototype.slice.call(arguments, 1)ctx.fn(...newArr) // ES6中的
'...' 展開(kāi)運(yùn)算符,可以展開(kāi)數(shù)組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)// 運(yùn)行試試 !
復(fù)制代碼函數(shù)的返回值,看以下栗子:var obj = {}
obj.value =
'alex.cheng'
function bar() {
return {value: this.value}
}
bar.call(obj)>>> {value:
"alex.cheng"}
復(fù)制代碼最終實(shí)現(xiàn)Function.prototype.myCall =
function (ctx) {var ctx = ctx || window // 如果傳入的ctx是null的話,就將ctx指向windowctx.fn = this// 將arguments轉(zhuǎn)化成數(shù)組,通過(guò)slice()方法截取數(shù)組除第一項(xiàng)以外的所有項(xiàng),并返回截取的數(shù)組var newArr = Array.prototype.slice.call(arguments, 1)var result = ctx.fn(...newArr) // ES6中的
'...' 展開(kāi)運(yùn)算符,可以展開(kāi)數(shù)組delete ctx.fn
return result // 返回ctx.fn的返回值
}var value =
'hey, this is a global_value .' // 定義一個(gè)全局變量var obj = {value:
'hello, obj.value'
}
function saySth(name, age) {
return {name,age,value: this.value}
}saySth.myCall(obj,
'alex.cheng', 18) // 傳入obj,saySth函數(shù)的this指向obj
>>> {name:
"alex.cheng", age: 18, value:
"hello, obj.value"}saySth.myCall(null,
'alex.cheng', 18) // 傳入null,saySth函數(shù)的this指向window
{name:
"haolun", age: 18, value:
"hey, this is a global_value ."}// 自己動(dòng)手試一試 @.@
復(fù)制代碼apply
apply的用法和call的用法一樣,唯一的區(qū)別,就是傳入的參數(shù)不同,apply需要傳入數(shù)組,例如 fn.apply( null, [ ] )
模擬實(shí)現(xiàn)也和call 相似,實(shí)現(xiàn)如下 :Function.prototype.myApply =
function (ctx) {var ctx = ctx || windowctx.fn = thisvar resultvar args = arguments[1] // 獲取傳入的數(shù)組
if (!args) { // 如果沒(méi)有傳入數(shù)組參數(shù),則直接調(diào)用ctx.fn方法result = ctx.fn()}
else {result = ctx.fn(...args) // 如果傳入了數(shù)組參數(shù),將數(shù)組參數(shù)采用ES6的
'...'擴(kuò)展運(yùn)算符將其展開(kāi)并傳入ctx.fn方法}delete ctx.fn
return result
}// 親自試一試 :)
Math.max.myApply(null, [1,2,3,4,55,44,33,22,11])
復(fù)制代碼
總結(jié)
以上是生活随笔為你收集整理的javascript之模拟call以及apply实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。