一、 在全局作用域中调用一个函数时,this总是指向Global对象(浏览器中就是window对象)
var name = 'May';var getName = function() { console.log(this === window); //true console.log(this.name); // 'May'}getName();
二、 当函数作为对象里的办法被调用时,this指向该对象
var name = 'May';var obj = { name: 'Lily', getName: function() { console.log(this.name); // 'Lily' }}obj.getName();
三、 当一个函数用作构造函数时(应用new关键字),this指向正在结构的新对象。如果构造函数返回的值不是一个对象,则默认返回this对象,看例子。
function Name() { this.name = 'May';}var obj = new Name();console.log(obj.name); // 'May'
function Name() { this.name = 'May'; return 'Lily';}var obj = new Name();console.log(obj.name); // 'May',因为返回的是字符串而不是对象
function Name() { this.name = 'May'; return { name: 'Lily' };}var obj = new Name();console.log(obj.name); // 'Lily'
四、事件监听中的this
被内联解决函数调用时,this指向所在的DOM元素
<div id="test" onclick="alert(this.id)">Click</div>
下面的alert显示test,但只有外层代码的this是这样的,如果像以下这种状况,this会指向window对象(非严格模式下),所以alert显示undefined,因为window中没有定义id
<div id="test" onclick="(function(){alert(this.id);})()"> Click2 </div>
当作为一个DOM事件处理函数时,this指向触发事件的元素
<div id="test">A</div>document.getElementById('test').onclick = function() { console.log(this.id); // test元素}
五、apply()和call()
这两个办法的用处都是在特定的作用域中调用函数,等同于设置函数体内this对象的值,扭转this指向。
apply()接管两个参数,第一个是在其中运行函数的作用域(this值),第二个是参数数组。
call()与apply()办法作用雷同,区别仅在于承受参数的形式不同,call()第一个参数是this值,传递给函数的参数必须一一列出来。
var name = 'May';var obj = { name: 'Lily', getName: function() { console.log(this.name); }}obj.getName.apply({ name: 'Mary' }); // 'Mary'obj.getName.apply(window); // 'May'obj.getName.call({ name: 'Jay' }); // 'Jay'obj.getName.call(window); // 'May'
// apply()与call()传参示例function add(a, b) { return a + b + this.num;}var o = { num: 1 };console.log(add.apply(o, [4, 3])); // 4+3+1 = 8console.log(add.call(o, 2, 2)); // 2+2+1 = 5
六、bind()
bind()办法被调用时,返回一个新的函数,新的函数的this被永恒绑定到了bind的第一个参数(bind的其余参数将作为新函数的参数供调用时应用)
var name = 'May';var obj = { name: 'Lily', getName: function(name) { console.log(this.name); console.log(name); }}var getName = obj.getName.bind({ name: 'Bind' }, 'Test');getName(); // 'Bind' 'Test'
七、箭头函数中的this
箭头函数的this值是定义时所在的对象而不是执行时所在的对象。
var name = 'May';var obj = { name: 'Lily', getName: () => { console.log(this.name); }}obj.getName(); // 输入的是'May'而不是'Lily'
总结:
绝大多数状况下,函数的this值取决于函数执行时的环境,而非函数申明时的环境。但箭头函数的this值放弃为闭合词法上下文的值,就是定义时所在的对象而不是执行时所在的对象。