call()、bind()、apply() 不是ES6的新特性。
- call() 和 apply() 方法早在ES3时期就已经存在了,它们用于调用函数并指定函数内部this的值。
- bind() 方法是在ES5中引入的,它用于创建一个新的函数,这个新函数的this值被绑定到指定的值。
ES6 主要引入了一些新的语法和特性,例如let和const、箭头函数、模板字符串、解构赋值、Promise、类和模块等。
call()、bind()、apply() 的区别:
- call() 方法接受一个参数列表,例如
fn.call(obj, arg1, arg2, ...)
- apply() 方法接受一个参数数组,例如
fn.apply(obj, [arg1, arg2, ...])
- bind() 方法返回一个新的函数,这个新函数的this值被绑定到指定的值,例如
const newFn = fn.bind(obj); newFn(arg1, arg2, ...)
使用场景:
- call() 和 apply() 常用于调用函数并改变函数内部的this值,例如借用其他对象的方法。
- bind() 常用于创建一个新的函数,这个新函数的this值被绑定到指定的值,例如事件处理函数中绑定this。
1.call()
一般我们修改this执行都使用call()方法可以理解为:临时放到对象里执行, 修改了函数中关键词 this 的指向。
看下面的代码,声明两个不同的对象里面都有属性x,我们写一个最简单的求和函数,进行演示call()怎么使用
call(‘参数一’,‘参数二’,‘参数三’,…)
参数一:要绑定给this的值,需要this指向的元素null、undefined的时候,默认指向window
参数二:参数列表
参数三:参数列表
//非严格模式
var m = { x: 10 }
var n = { x: 100 }
function add(y, z) {
return this.x + y + z
}
// 短暂访问m 携带一些礼物(参数)
console.log(add.call(m, 20, 30))//这里时候函数add里面的this指向m对象
console.log(add.call(n, 200, 300));//这里时候函数add里面的this指向对象
严格模式
第一个参数是谁,this就指向谁,包括null和undefined,如果不传参数this就是undefined
2.bind()
这个方法比较特殊不会立刻执行需要点击以后才会执行。看下面代码,代码中对比了call()和bind(),两者语法相同,bind()方法用的场景和call()有一些区别
bind()把 实参 和 运行时所在对象绑定 在函数上, 返回一个新的函数; 后续可以随时触发
<body>
<!-- 事件 -->
<!-- 在 元素上进行一些操作时, 会触发相关的事件 -->
<!-- onclick : 当点击时触发代码 -->
<!-- 耦合性太强: HTML中 掺杂了大量的 JS代码 -->
<button onclick="show.call(emp, '泡泡', 18)">Click Me</button>
<!-- 触发绑定的函数 -->
<button onclick="m()">Click!!</button>
<script>
var emp = { eid: '11001' }
function show(name, age) {
alert("Hello" + name + age + this.eid)
}
// bind: 可以把函数 和 其运行时所在对象 和 实参 绑定在一起, 返回新的函数
var m = show.bind(emp, '凯凯', 32)
// bind仅绑定, 不会触发函数的执行
console.dir(m)
</script>
</body>
3.apply()
apply()可以改变this的指向, 可以把 数组 打散成 1个1个 实参, 传递给函数使用
apply(参数一,参数二)接受两个参数,
参数一:要绑定给this的值
参数是二:一个参数数组。
注意:当第一个参数为null、undefined的时候,默认指向window。
看下面代码 和call()做了比较,区别在于传递的参数不同
<script>
var m = { x: 10 }
var n = { x: 100 }
function add(y, z) {
return this.x + y + z
}
// 短暂访问m 携带一些礼物(参数)
console.log(add.call(m, 20, 30))
console.log(add.call(n, 200, 300));
// apply: 申请 -- 申请到某个对象中执行
// 申请到 m对象中执行, 携带一些礼物--打包起来的
console.log(add.apply(m, [20, 30])) //实参放数组里传递
console.log(add.apply(n, [200, 300]))
</script>
总结
说实话工作中基本很少用到,除非你在封装一些底层框架会用到属于封装框架必备。面试基本都会问一下这个三个,区别就是传递的参数不同,bind()不是立刻执行而是点击以后才会执行并且是返回一个改变了上下文 this 后的函数,便于稍后调用。而原函数 中的 this 并没有被改变,依旧指向原来该指向的地方。