SOURCE

/**
 *  方法调用:
 *  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 命令行工具 X clear

                    
>
console