网站首页 > 技术文章 正文
总结一句话:改变函数内部的 this 指向,并执行函数。
call、apply 是 Function 构造函数原型对象上的方法,所有的函数(包括call)都可以调用 call 和 apply。
call
先看一下原生call的效果(运行在浏览器环境)
let context = {
name: 'z'
}
// 全局环境, 用let变量不会挂在window上
var name = 'j'
function say(age,sex){
console.log(this.name+age+sex)
}
say.call(context,12,1) // z121
say.call(null,18,0) // j180
我们稍加分析,将成call做的事情拆解为三步:
- 先把方法say挂在call的第一个参数,context的属性下(context指上下文,this所指向的新执行环境)
- 执行 context.say(age, sex),并传入参数
- 删除 context.say,不能侵入性修改原数据
按照这三步我们复现一下 写一个myCall
Function.prototype.myCall = function(context) {
// 设置一个参数默认值,浏览器环境默认window,node环境是global
context = context ? context : window;
// 原函数调用call函数,所以this指向原函数本身,即 say
context.fn = this
// 获取除掉第一个context外的参数
let args = []
for(let i=1;i<arguments.length;i++){
args.push('arguments['+i+']')
}
// 调用函数
var result = eval('context.fn('+ args +')')
// 删除增加的属性
delete context.fn
// 返回执行结果
return result
}
执行一下
let context = {
name: 'z'
}
// 全局环境, 用let变量不会挂在window上
var name = 'j'
function say(age,sex){
console.log(this.name+age+sex)
}
say.myCall(context,12,1) // z121
say.myCall(null,18,0) // j180
完美复现,okkkk~~~
解释一下eval问题,之所以这样写,是因为之前还没有结构啊,Array.from类数组转数组语法什么的。eval遇到数组会调用 args.toString(),解析后是这样的
context.fn(arguments[1], arguments[2], ...)
apply
apply与call基本相同,只是额外参数是数组形式
Function.prototype.myApply = function (context,args){
context = context ? context : window
context.fn = this
// 判断是否传递额外参数,如果没有直接执行函数即可
if(!args) return context.fn()
var result = eval('context.fn('+ args +')')
delete context.fn
return result
}
bind
bind下篇文章讲,关注一下哈哈~~~
猜你喜欢
- 2024-11-16 3.1 Python高级编程-函数式编程工具
- 2024-11-16 面向对象编程的一些思考(面向对象编程的理解)
- 2024-11-16 知识总结-Java8 Stream函数式编程
- 2024-11-16 bind、call、apply 区别?如何实现一个bind?
- 2024-11-16 Javascript基础重拾笔记之手写apply、call
- 2024-11-16 java 8新特性 常用内置函数式接口
- 2024-11-16 7、JavaScript 内置的常用对象有哪些?该对象常用的方法(必会)
- 2024-11-16 Java中“::”是什么含义(java中+是什么)
- 2024-11-16 Java 8 中的 Function:让代码从繁琐到简洁的魔法工具
- 2024-11-16 13万字详细分析JDK中Stream的实现原理(中)
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-