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实现的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。