标签:str ber 包装 line 不能 val 监听 script 多个
前言:上一篇简单说了this的飘忽不定,有时,需要把this
固定下来,避免出现意想不到的情况。JavaScript 提供了call
、apply
、bind
这三个方法,来切换/固定this
的指向。(出来混总是要还的)。
1、call()
函数实例的call
方法,可以指定函数内部this
的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。
var obj = {}; var f = function () { return this; }; f() === window // true f.call(obj) === obj // true
call
方法的参数,应该是一个对象。如果参数为空、null
和undefined
,则默认传入全局对象。
var n = 123; var obj = { n: 456 }; function a() { console.log(this.n); } a.call() // 123 a.call(null) // 123 a.call(undefined) // 123 a.call(window) // 123 a.call(obj) // 456
call
方法的参数是一个原始值,那么这个原始值会自动转成对应的包装对象,然后传入call
方法。
var f = function () { return this; }; f.call(5) // Number {[[PrimitiveValue]]: 5}
call
方法还可以接受多个参数。
function add(a, b) { return a + b; } add.call(this, 1, 2) // 3
call
方法的一个应用是调用对象的原生方法。(这也是call()方法实现继承的原因)
var obj = {}; obj.hasOwnProperty(‘toString‘) // false // 覆盖掉继承的 hasOwnProperty 方法 obj.hasOwnProperty = function () { return true; }; obj.hasOwnProperty(‘toString‘) // true Object.prototype.hasOwnProperty.call(obj, ‘toString‘) // false
上面代码中,hasOwnProperty
是obj
对象继承的方法,如果这个方法一旦被覆盖,就不会得到正确结果。call
方法可以解决这个问题,它将hasOwnProperty
方法的原始定义放到obj
对象上执行,这样无论obj
上有没有同名方法,都不会影响结果。
2、apply()
apply
方法的作用与call
方法类似,也是改变this
指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数。
func.apply(thisValue, [arg1, arg2, ...])//apply()格式 //例子对比 function f(x, y){ console.log(x + y); } f.call(null, 1, 1) // 2 f.apply(null, [1, 1]) //
(1)找出数组最大元素
JavaScript 不提供找出数组最大元素的函数。结合使用apply
方法和Math.max
方法,就可以返回数组的最大元素。
var a = [10, 2, 4, 15, 9]; Math.max.apply(null, a) // 1
(2)将数组的空元素变为undefined
通过apply
方法,利用Array
构造函数将数组的空元素变成undefined
。
Array.apply(null, [‘a‘, ,‘b‘]) // [ ‘a‘, undefined, ‘b‘ ] var a = [‘a‘, , ‘b‘]; function print(i) { console.log(i); } a.forEach(print) // a // b Array.apply(null, a).forEach(print) // a // undefined // b
(3)转换类似数组的对象
另外,利用数组对象的slice
方法,可以将一个类似数组的对象(比如arguments
对象)转为真正的数组。
Array.prototype.slice.apply({0: 1, length: 1}) // [1] Array.prototype.slice.apply({0: 1}) // [] Array.prototype.slice.apply({0: 1, length: 2}) // [1, undefined] Array.prototype.slice.apply({length: 1}) // [undefined]
3、bind()
bind()
方法用于将函数体内的this
绑定到某个对象,然后返回一个新函数。
var counter = { count: 0, inc: function () { this.count++; } }; var func = counter.inc.bind(counter); func(); counter.count // 1 var counter = { count: 0, inc: function () { this.count++; } }; var obj = { count: 100 }; var func = counter.inc.bind(obj); func(); obj.count // 101
bind()
还可以接受更多的参数,将这些参数绑定原函数的参数。
var add = function (x, y) { return x * this.m + y * this.n; } var obj = { m: 2, n: 2 }; var newAdd = add.bind(obj, 5); newAdd(5) // 20
bind()
方法每运行一次,就返回一个新函数,这会产生一些问题。比如,监听事件的时候,不能写成下面这样。
element.addEventListener(‘click‘, o.m.bind(o));
正确的方法是写成下面这样:
var listener = o.m.bind(o); element.addEventListener(‘click‘, listener); // ... element.removeEventListener(‘click‘, listener);
js绑定 this 的方法 call 、apply、bind 方法
标签:str ber 包装 line 不能 val 监听 script 多个
原文地址:https://www.cnblogs.com/xuwupiaomiao/p/12781322.html