js改变this指向的方法(call apply bind)
- 在函数中使用this
function foo(c, d) {
return this.a + this.b + c + d
}global.a = 3
global.b = 4// foo执行时,this没有明确的指向,默认指向全局对象global
// nodejs中是global,browser中是window
foo(3, 4)// 14
call apply bind是函数Function原型的方法,所有函数继承自Function.prototype
foo.call === Function.prototype.call// true
foo.apply === Function.prototype.apply// true
foo.bind === Function.prototype.bind// true
- call() apply()
let o = {a: 1, b: 2}// foo.call(obj, ...[arguments])
foo.call(o, 3, 4)// 10
foo.call(null, 3, 4)// 14
foo.call(undefined, 3, 4)// 14
foo.call(global, 3, 4)// 14// foo.apply(obj, [arguments])
foo.apply(o, [3, 4])// 10
foo.apply(null, [3, 4]) // 14
call apply bind的第一个参数如果不是对象,会先调用内部的ToObject方法转换成对象。
function foo(){
return typeof this
}// 分别调用Number和String的constructor
foo.call(1)// object, new Number(1)
foo.call('a')// object, new String('a')
es6支持使用扩展运算符,一些情况下可以不再使用call、apply、bind。
// 求数组最大值
let arr = [4, 3, 2, 1]
Math.max.call(null, ...arr) // 4
Math.max.apply(null, arr)// 4
Math.max(...arr)// 4// 数据类型判断
Object.prototype.toString.call(1)// [object Number]
Object.prototype.toString.call('a') // [object String]new (Date.bind.apply(Date, [null, 2018, 5, 26]))
new Date(...[2018, 5, 26])
- bind()
let o = {a: 1, b: 2}let f1 = foo.bind(o, 3, 4)
let f2 = f1.bind(null, 10, 10)f1()// 10
f2()// 10, 并没有绑定global, 参数c和d的值也没有改变
f1 === f2// false, f1和f2并不相等
f1.call(null, 10, 10)// 10, 在f1上使用call仍然没有改变
推荐阅读
- 2018-02-06第三天|2018-02-06第三天 不能再了,反思到位就差改变
- 改变自己,先从自我反思开始
- 越努力越幸福
- 关于this的一些问题(1)
- #微习惯可以改变你#第2周复盘
- 如何启动改变
- 改变没有对错
- iview|iview upload 动态改变上传参数
- 《习惯陷阱》(改变思维习惯,突破人生局限,成为你想成为的人)
- 改变不了社会就改变自己()