JS高级——手写call()、apply()、bind()

0、call、apply、bind的区别

bind,call,apply的作用都是用来改变this指向的

  1. call方法
    call方法的第一个参数是this的指向
    后面传入的是一个参数列表(注意和apply传参的区别)。当一个参数为null或undefined的时候,函数中的this默认指向window(在浏览器中),和apply一样,call也只是临时改变一次this指向,并立即执行。

  2. apply方法:使用apply方法改变this指向后原函数会立即执行,且此方法只是临时改变thi指向一次。
    apply接受两个参数:
    第一个参数是this的指向
    第二个参数是函数接受的参数,以数组的形式传入,且当第一个参数为null、undefined的时候,函数中的this默认指向window(在浏览器中)

在这里插入图片描述
3. bind方法
bind方法和call很相似
第一参数也是this的指向
后面传入的也是一个参数列表(但是这个参数列表可以分多次传入,call则必须一次性传入所有参数),但是它改变this指向后不会立即执行,而是返回一个永久改变this指向的函数

在这里插入图片描述
在这里插入图片描述

一、call函数的实现

在这里插入图片描述

在这里插入图片描述

// 给所有的函数添加一个myCall方法
Function.prototype.myCall = function (thisArg, ...args) {// 1. 获取需要被执行的函数var fn = this// 对thisArg转成对象类型(防止它传入的是非对象类型的参数)thisArg = thisArg ? Object(thisArg) : window// 2.为调用myCall的函数绑定this(利用了js的隐式绑定)thisArg.fn = fn// 3.调用需要被执行的函数const result = thisArg.fn(...args)delete thisArg.fn// 4.将函数的调用结果返回return result
}const result = sum.myCall('aaa', 10, 20)
console.log(result)function sum(num1, num2) {console.log('sum函数被执行了', this)return num1 + num2
}// const result = sum.call('aaa', 20, 30)
// console.log(result)

二、apply函数的实现

在这里插入图片描述

Function.prototype.myApply = function (thisArg, argArr) {// 1. 获取调用myApply的函数var fn = this// 2. 将thisArg转成对象类型,否则后续无法通过thisArg.fn绑定this,// 且若thisArg没有传值,则让this绑定为windowthisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg) : windowthisArg.fn = fn// 3. 对argArr进行处理,确保它有传值并且为数组,// 否则后续通过...argArr解构会报错:因为如果argArr不传值时为undefined,...undefined解构就会报错argArr = argArr ? argArr : []// 4. 执行函数const result = thisArg.fn(...argArr)delete thisArg.fn// 5. 将函数执行结果返回return result
}
function sum(num1, num2) {console.log(this, num1, num2)return num1 + num2
}
const result1 = sum.myApply('aaa', [10, 20])
console.log(result1)
const result2 = sum.myApply(0)
console.log(result2)
sum.apply('aaa', [10, 20])
sum.apply(0)

三、bind函数的实现

bind方法和call很相似
第一参数也是this的指向
后面传入的也是一个参数列表(但是这个参数列表可以分多次传入,call则必须一次性传入所有参数),但是它改变this指向后不会立即执行,而是返回一个永久改变this指向的函数
在这里插入图片描述
在这里插入图片描述

Function.prototype.myBind = function (thisArg, ...argArr) {// 1.获取道真实需要调用的函数var fn = this// 2.处理thisArg不传值的情况,不传值则默认函数里的this绑定window,传了值则还需要确保它为对象类型,否则后续thisArg.fn = fn会报错thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg) : windowvar proxyFn = function (...args) {// 3.绑定this(这里用了js的隐式绑定)thisArg.fn = fn// 4.将函数传入的剩余参数进行合并,用于实现bind函数的第二个参数列表可以分多次传入const finalArgArr = [...argArr, ...args]// 5.调用函数const result = thisArg.fn(...finalArgArr)delete thisArg.fn// 6.将函数执行结果返回return result}return proxyFn
}
function sum(num1, num2) {console.log(this, num1, num2)return num1 + num2
}
const newSum = sum.myBind('aaa', 10, 20) // 参数列表可以分多次传入
const result = newSum(30, 40) // 参数列表可以分多次传入
console.log(result)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js文章QQ空间分享

<!--示例一--> <div id"ckepop" classfeixiangjias> <a href"javascript:" class"jiathis jiathis_txt jtico jtico_jiathis" target"_blank">分享到&#xff1a;</a> <a class"jiathis_button_qzo…

JS高级——深入剖析函数中的this指向问题

一、this到底指向什么呢&#xff1f; 我们先说一个最简单的&#xff0c;this在全局作用域下指向什么&#xff1f; 这个问题非常容易回答&#xff0c;在浏览器中测试就是指向window 但是&#xff0c;开发中很少直接在全局作用于下去使用this&#xff0c;通常都是在函数中使用…

JS高级——arguments参数详解

一、认识arguments arguments 是一个 对应于 传递函数的参数 的 类数组(array-like)对象。 array-like意味着它不是一个数组类型&#xff0c;而是一个对象类型&#xff1a; 但是它却拥有数组的一些特性&#xff0c;比如说length&#xff0c;比如可以通过index索引来访问&…

php 函数有命名空间吗_解析 ThinkPHP 的命名空间

php中文网最新课程每日17点准时技术干货分享大家都知道由于PHP语法里不支持函数重载机制&#xff0c;如果一个应用里有两个同名的方法&#xff0c;怎么办呢&#xff1f;在Yii 框架为了避免名字重复引起问题&#xff0c;全部的类前边都有 C 字样&#xff0c;而在ThinkPHP里就引入…

JS高级——纯函数、柯里化(手写自动柯里化函数)、组合函数(手写自动组合函数)

一、理解JavaScript纯函数 函数式编程中有一个非常重要的概念叫纯函数&#xff0c;JavaScript符合函数式编程的范式&#xff0c;所以也有纯函数的概念&#xff1b; 在react开发中纯函数是被多次提及的&#xff1b;比如react中组件就被要求像是一个纯函数&#xff08;为什么是…

三包围结构的字是什么样的_拼音带kun的字大全_50个拼音含kun的字组词

原标题&#xff1a;拼音带kun的字大全_50个拼音含kun的字组词1、昆(kūn)&#xff0c;8画&#xff0c;上下结构&#xff0c;部首&#xff1a;曰(日)组词&#xff1a;昆虫(kūn chng) | 昆曲(kūn qǔ) | 昆山(kūn shān) | 昆仲(kūn zhng) | 昆吾(kūn w) | 昆仑(kūn ln) |2…

JS高级——with语句、eval函数、严格模式

一、with语句 with语句的作用&#xff1a;扩展一个语句的作用域链。 不建议使用with语句&#xff0c;因为它可能是混淆错误和兼容性问题的根源。并且&#xff0c;在浏览器开启严格模式下&#xff0c;使用with会报错&#xff1a; 二、eval函数 eval是一个特殊的函数&#x…

JS面向对象——Object.defineProperty

一、JavaScript的面向对象 JavaScript其实支持多种编程范式的&#xff0c;包括函数式编程和面向对象编程&#xff1a; JavaScript中的对象被设计成一组属性的无序集合&#xff0c;像是一个哈希表&#xff0c;有key和value组成&#xff1b;key是一个标识符名称&#xff0c;val…

json字符串和字典类型的相互转换(转载)

转自&#xff1a;http://www.cnblogs.com/YUTOUYUWEI/p/5585863.html 在开发过程中&#xff0c;有时候需要将json字符串转为字典类型&#xff0c;反之亦然&#xff0c;通常采用.Net的开源类库Newtonsoft.Json进行序列化&#xff0c;这里我也是采用这个&#xff0c;不过我更喜欢…

JS高级——对象的原型__proto__、函数的原型prototype、构造函数

一、认识构造函数 我们先理解什么是构造函数&#xff1f; 构造函数也称之为构造器&#xff08;constructor&#xff09;&#xff0c;通常是我们在创建对象时会调用的函数&#xff1b;在其他面向的编程语言里面&#xff0c;构造函数是存在于类中的一个方法&#xff0c;称之为构造…

JS面向对象——原型链、通过原型链实现继承、借用构造函数实现继承

一、JavaScript原型链 在真正实现继承之前&#xff0c;我们先来理解一个非常重要的概念&#xff1a;原型链。 我们知道&#xff0c;从一个对象上获取属性&#xff0c;如果在当前对象中没有获取到就会去它的原型&#xff08;__proto__&#xff09;上面获取&#xff1a; 二、…

JS面向对象——原型式继承函数、寄生式继承函数、寄生组合式继承

一、原型式继承函数 回顾一下JavaScript想实现继承的目的&#xff1a;重复利用另外一个对象的属性和方法. 最终的目的&#xff1a;student对象的原型指向了person对象&#xff1b; 二、寄生式继承函数 寄生式(Parasitic)继承是与原型式继承紧密相关的一种思想, 并且同样由道格…

JS面向对象——Object对象的方法补充、原型继承关系图

一、Object.create() 这个方法用于创建一个新对象。被创建的对象的__proto__指向create函数第一个参数的原型对象prototype&#xff0c;在创建新对象时可以通过create函数第二个参数指定一些属性。 二、Object.hasOwnProperty() 对象是否有某一个属于自己的属性&#xff08…

JS面向对象——class定义类、类的构造函数、实例方法、访问器方法、静态方法、继承、super、多态

一、认识class定义类 我们会发现&#xff0c;按照前面的构造函数形式创建 类&#xff0c;不仅仅和编写普通的函数过于相似&#xff0c;而且代码并不容易理解。 在ES6&#xff08;ECMAScript2015&#xff09;新的标准中使用了class关键字来直接定义类&#xff1b;但是类本质上依…

ES6(一)——字面量的增强、解构、let/const、块级作用域、暂时性死区

一、字面量的增强 ES6中对 对象字面量 进行了增强&#xff0c;称之为 Enhanced object literals&#xff08;增强对象字面量&#xff09;。 字面量的增强主要包括下面几部分&#xff1a; 属性的简写&#xff1a;Property Shorthand方法的简写&#xff1a;Method Shorthand计算…

MapReduce算法形式四:mapjoin

案例四&#xff1a;mapjoin&#xff08;对个map共同输入&#xff0c;一个reduce&#xff09; 这个方法主要解决的是&#xff0c;几个表之间的比较&#xff0c;类似于数据库的内外连接&#xff0c;还有一些左右连接之类的&#xff0c;简而言之就是&#xff0c;A表没有的B表有&am…

ES6(二)——字符串模板、标签模板字符串、函数的默认参数、剩余参数、数组对象的展开语法、数值的表示、Symbol

一、字符串模板基本使用 在ES6之前&#xff0c;如果我们想要将字符串和一些动态的变量&#xff08;标识符&#xff09;拼接到一起&#xff0c;是非常麻烦和丑陋的&#xff08;ugly&#xff09;。 ES6允许我们使用字符串模板来嵌入JS的变量或者表达式来进行拼接&#xff1a; 首…

ES6(三)——Set、WeakSet、Map、WeakMap

一、Set的基本使用 在ES6之前&#xff0c;我们存储数据的结构主要有两种&#xff1a;数组、对象。 在ES6中新增了另外两种数据结构&#xff1a;Set、Map&#xff0c;以及它们的另外形式WeakSet、WeakMap。 Set是一个新增的数据结构&#xff0c;可以用来保存数据&#xff0c;类…

ES6~ES12——Array Includes、Object values、Object entries、Object fromEntries、flat、flatMap、空值合并运算符、可选链等

一、ES7 - Array Includes 在ES7之前&#xff0c;如果我们想判断一个数组中是否包含某个元素&#xff0c;需要通过 indexOf 获取结果&#xff0c;并且判断是否为 -1。 在ES7中&#xff0c;我们可以通过includes来判断一个数组中是否包含一个指定的元素&#xff0c;根据情况&…

移除通知的时机

链接 结论 最好是在不需要的时候就移除掉。 如果不是特别苛刻&#xff0c;可以直接在dealloc函数里写。因为dealloc函数一定会被调用的。 在dealloc函数中移除的可能问题 由于dealloc在Runloop结束时会被调用。如果在Runloop调用之前&#xff0c;又有一个通知到来&#xff0c;会…