module1.init($div) // 语法糖
module1.init.call(module1,$div) // 等价
详解
this 永远在函数调用时确定,只是由于语法糖的存在,我们在实际使用时会受到使用场景(浏览器/库)内部this指向的不同的影响。
- 由于语法糖的存在,我们在平常调用函数时很少使用.call(this,argument)的形式
- 所以如果你自己指定this,就call
例子
let module1 = {
elment:null,
init: ($div)=>{
this.element = $div
this.bindEvents()
},
bindEvents:function(){
let $div = this.element
$div.on('click', fucntion(e){
console.log('div is clicked')
})
$div.on('click', 'button', this.onClickButton)
// 浏览器
// when user click button
// fn.call('button', {target:'button',currentTarget:'button'})
// 所以这里只跟调用时有关
$div.on('change', 'input', function(e){
console.log(xxx)
})
},
}
总结
一般情况下,
- 当函数作为对象方法调用时,this指向调用该方法最靠近的对象成员,因此:
- 当函数被赋予另一个变量时,函数内部的this的指向会改变,其原因是调用他的对象有变更
- 可以理解为对象即执行该函数的环境,在顶级作用域下执行函数,this指向全局变量(浏览器中为window)
var a = {
b: {
m: function() {
console.log(this.p);
},
p: 'Hello'
}
};
var hello = a.b.m;
hello() // undefined
var hello = a.b
hello() // Hello
- 构造函数中的this默认绑定为被创建的新对象
原理:
- 创建一个空对象,作为将要返回的对象实例
- 将这个空对象的原型指向prototype属性
- 将这个空对象的值赋给函数内部的this关键字
- 开始执行构造函数内部代码
参考前面的方法,总结为
var a = function(){
this.balaba = 123;
}
var b
b = {}
Object.setPrototypeOf(b, a)
a.call(b)
当函数被当做事件处理函数时,this指向触发事件的函数
内联事件处理函数的this指向监听器所在的DOM元素
当函数作为嵌套函数调用时, this指向全局对象(非严格模式下)或者undefined(严格模式)而不是其外包函数的上下文
var o = {
f1: function () {
console.log(this);
var f2 = function () {
console.log(this);
}();
}
}
o.f1()
// Object
// Window
// 上面等价于下面
var temp = function () {
console.log(this);
};
var o = {
f1: function () {
console.log(this);
var f2 = temp();
}
}
// 解决办法
var o = {
f1: function() {
console.log(this);
var that = this;
var f2 = function() {
console.log(that);
}();
}
}
o.f1()
// Object
// Object
怎么看this
- console.log()
- 看浏览器/jQuery/DOM 源代码
- 看API 文档
bind()
bind()
会返回一个新的函数,该函数有指定的this,且不被call()
/ apply()
bind的使用例子
根据前面总结的第3条和第5,如果需要在一个函数中的事件监听设置this指向外包函数的this,可以用bind绑定this的指向,否则,监听事件触发时this会指向触发事件的元素。
var box = document.getElementById('box');
box.x = 'box'
function outFunc() {
this.x = 'outFunc';//给全局对象window.x赋值(相当于赋值全局变量)
box.addEventListener('click', func.bind(this), false); // bind(this) 的this 指向outFunc() 中的this,又等于指向window
}
function func() {
console.log(this.x); //输出outFunc 使用bind设置this的值
}
参考:
JS中的this简单描述
addEventListener中事件函数的this指向
MDN - JavaScript - this