前言
ES6新特性中this指向的问题,有时候this的指向并不是我们想要的,我们可以通过call()、bind()、apply()这三个方法去修改,这三个都可以修改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 并没有被改变,依旧指向原来该指向的地方。
注:欢迎大家多多指教,指正错误。