/**
* 方法调用:
* 1.是指通过方法对象来调用其方法函数,它是!!!对象.方法函数()!!!这样的形式调用。这种情况下,函数中的this指向调用该方法的对象。
* 2.特例是bind影响
*
*/
const obj = {
// 第一种方式,定义对象的时候定义其方法
test () {
console.log(this === obj)
}
};
// 第二种方式,对象定义好之后为其附加一个方法(函数表达式)
obj.test2 = function(){
console.log(this === obj);
}
function t() {
console.log(this === obj)
}
obj.test3 = t;
// 这也是为对象附加一个方法函数
// 但是这个函数绑定了一个不是obj的其他对象
obj.test4 = (function(){
console.log(this === obj);
}).bind({})
obj.test()
obj.test2()
obj.test3()
obj.test4()
// 方法中this指向全局对象的情况
// 方法中,而不是方法调用中。方法中的this指向全局对象,如果不是因为bind(),那就一定是因为不是用的方法调试。
const obj2 = {
test () {
console.log(this === obj2);
}
}
const testObj2 = obj2.test;
testObj2(); // 指向全局
// 常常将一个对象方法作为回调传递给某个函数后,却发现运行结果与预期不符。因为忽略了调用方式的影响。
// 下面例子是在进行封装之后特别容易遇到的问题
class Handlers {
// 这里$button 假设是一个指向某个按钮的jQuery对象
constructor(data,$button) {
this.data = data;
$button.on('click',this.onButtonClick);
}
onButtonClick(e) {
console.log(this.data);
}
}
const handlers = new Handlers("String Data",$('#someButton'))
// 对#someButton进行点击操作之后,输出undefined,预期是输出string data;
// 问题: this.onButtonClick作为一个参数传入on()之后,事件触发时,理论上是对这个函数进行的直接调用,而不是方法调用
// 所以this会指向全局对象--但实际上由于调用事件处理函数的时候,this指向会绑定到触发事件的DOM元素上。
// 解决办法
var _this = this;
$button.on('click',function(){
_this.onButtonClick();
});
// bind()解决
$button.on("click",this.onButtonClick.bind(this));
// es6中可以通过箭头函数来处理
$button.on("click",e => this.onButtonClick(e));
console