欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 前端技术 > javascript >内容正文

javascript

javascript之模拟call以及apply实现

发布时间:2025/3/21 javascript 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 javascript之模拟call以及apply实现 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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.fnreturn 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.fnreturn result }// 亲自试一试 :) Math.max.myApply(null, [1,2,3,4,55,44,33,22,11]) 复制代码

    总结

    以上是生活随笔为你收集整理的javascript之模拟call以及apply实现的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。