call、apply 以及 bind 的区别和用法
call、apply、bind
call和apply共同点
- 共同点:改变函数执行时的上下文,将一个对象的方法交给另一个对象来执行,并且是立即执行的
- call和apply的对象,必须是一个函数Function
call和apply区别
call的写法
Function.call(obj, [param1[, param2[, ...[, paramN]]]])
需要注意以下几点:
- 调用call的对象,必须是个函数Function
- call的第一个参数,是一个对象,Function的调用者,将会指向这个对象。如果不传,则默认为全局对象window
- 第二个参数开始,可以接收任意个参数,每个参数会映射到相应位置的Function的参数上。
- 但是如果将所有的参数作为数组传入,他们会作为一个整体映射到Function对应的第一个参数上,之后参数都为空
function func(a,b,c) {}
func.call(obj, 1,2,3) // func接收到的参数为1,2,3
func.call(obj, [1,2,3]) // func接收到的参数为[1,2,3], undefined, undefined
apply的写法
Function.apply(obj[, argArray])
需要注意的是:
- 它的调用者必须是函数Function,并且只接受两个参数,第一个参数的规则与call一致
- 第二个参数,必须是数组或者类数组,他们会被转换成类数组,传入到Function中,并且会被映射到Function对应的参数上,
func.apply(obj, [1,2,3]) // func接收到的参数是1,2,3
func.apply(obj, {0:1, 1:2, 2:3, length: 3}) // func接收到的参数是1,2,3
什么是类数组
- 具备与数组特征类似的对象
- 类数组无法使用forEach、splice、push等数组原型链上的方法
call和apply的用途
call的使用场景
- 对象的继承
function superClass() {this.a = 1this.print = function() {console.log(this.a)}
}
function subClass() {superClass.call(this)this.print()
}
subClass() // 1
- 借用方法* 类数组,如果想使用Array原型链上的方法*
let demoNodes = Array.prototype.slice.call(document.getElementsByTagName("*"))
apply 的用法
- Math.max,用来获取数组中最大的一项*
let max = Math.max.apply(null, array)
- 实现两个数组合并
let arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
Array.prototype.push.apply(arr1, arr2)
console.log(arr1) // [1, 2, 3, 4, 5, 6]
bind的使用
bind()方法创建一个新的函数,在调用时设置this关键字为提供的值,并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项
Function.bind(thisArg, arg1, arg2])
- bind方法与apply、call比较类似,也能改变函数体内的this指向,不同的是,bind方法的返回值是函数,并且需要稍后调用,才会执行。而apply和call则是立即调用
- 如果bind的第一个参数是null或者undefined,this就指向全局对象window
function add (a, b) {return a + b;
}
function sub (a, b) {return a - b;
}
add.bind(sub, 5, 3); // 这时,并不会返回 8
add.bind(sub, 5, 3)(); // 调用后,返回 8
总结
- call 和 apply 的主要作用,是改变对象的执行上下文,并且是立即执行的。它们在参数上的写法略有区别。* bind 也能改变对象的执行上下文,它与 call 和 apply 不同的是,返回值是一个函数,并且需要稍后再调用一下,才会执行。bind的模拟实现
=========
bind
bind()方法创建一个新函数,当这个新函数被调用时,bind()的第一个参数将作为它运行时的this,之后的一序列参数将会在传递的实参钱传入作为它的参数
function fn(a, b, c) {return a + b + c;
}
var _fn = fn.bind(null, 10);
var ans = _fn(20, 30); // 60
它的特点:
1.返回一个函数;
2.可以传入参数
实现bind最终代码
Function.prototype.bind1 = function(context) {if (typeof this !== 'function') {throw new Error('Function.prototype.bind --what is trying to be bound is not callable')}var self = thisvar args = Array.prototype.slice.call(arguments, 1)var fNOP = function () {}var fBound = function() {var bindArgs = Array.prototype.slice.call(arguments) // 当作为构造函数时,this 指向实例,此时结果为 true,将绑定函数的 this 指向该实例,可以让实例获得来自绑定函数的值// 以上面的是 demo 为例,如果改成 `this instanceof fBound ? null : context`,实例只是一个空对象,将 null 改成 this ,实例会具有 habit 属性// 当作为普通函数时,this 指向 window,此时结果为 false,将绑定函数的 this 指向 contextreturn self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs))}fNOP.prototype = this.prototypefBound.prototype = new fNOP()return fBound
}
call、apply 以及 bind 的区别和用法相关推荐
- call(),apply()和bind()的区别和应用以及扩展
首先三个方法的作用: 1:都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域. 2:都是改变this的指向方向 区别: call()和apply()接受参数的方 ...
- call apply 和 bind的区别
apply 和call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Ja ...
- call、apply、bind的区别,模拟call、apply和bind的实现
bind:bind绑定完this的指向后会返回一个新的函数体,不会被立即调用 call&apply:绑定完this的指向后会立即调用 call与apply的区别: call:第 ...
- call和apply和bind的区别
都是修改function内在的this的指向 如果第一个参数传入的是null的话,那么浏览器中默认是window,node中默认是global,但是函数体内部如果是严格模式,那么this仍然是null ...
- call()、apply()、bind()的区别
函数对象方法 call().apply()这个两个都是函数对象的方法.需要通过函数对象调用 当对函数调用call()和apply().都会调用函数执行 /* call()和apply()是函数对象的两 ...
- call、apply、bind的区别?(面试题-JavaScript部分)
共同点: 可以改变this指向 语法: 函数.call().函数.apply().函数.bind() 不同点: 1. call.apply可以立即执行. bind不会立即执行,因为bind返回的是一个 ...
- Js中apply与call的区别与用法
解析: apply与call是更改对象的内部指针,即改变对象的this指向的内容. call与apply的第一个参数都是要传入给当前对象的对象,及函数内部的this.后面的参数都是传递给当前对象的参数 ...
- call、apply、bind 用法和区别
js 中,每个函数的原型都指向Function.prototype对象,因此,每个函数都会有apply,call,和bind方法,这些方法继承于Function,都是用于改变函数执行时的上下文,从而改 ...
- call()、apply()、bind()的使用和区别以及使用场景
call().apply().bind()的共同点: 都可以改变this指向 call的使用 var str = 'window'; var obj = { str: 'obj内的str' }; fu ...
最新文章
- 技术面试的时候应该了解公司点什么
- 黑马程序员C语言基础(第六天)指针
- java关于23种设计模式的有趣见解
- java 日历选择天_Java程序使用Java日历将天添加到当前日期
- 小朋友学数据结构(3):二叉树的建立和遍历
- js怎么设置z index.html,HTML5 Canvas set z-index
- 教你如何定位及优化SQL语句的性能问题
- 定时任务---SpringBoot
- 检测Java Web应用程序而无需修改其源代码
- Python脚本实现启停app获取资源占比信息
- Opencv3 Robert算子 Sobel算子 拉普拉斯算子 自定义卷积核——实现渐进模糊
- ajax与easyui树节点,easyUI 树形列表 想实现 类似于according 的效果 怎么办?
- android密码用户名和密码错误,Android之输入用户名和密码验证
- FIR与IIR滤波器
- vm安装win7 office2013
- NYOJ 首字母变大写
- 12个乒乓球称重问题
- 3dTile技术研究-概念详述(5)
- leetcode阶段总结——拓扑排序
- 标准紧固件、垫片、轴环