理解JS中this的指向
每个函数都有它自己的this
值,在绝大多数情况下,this
指向调用了函数的那个对象。
this
的指向,我总结出了以下几种情况: 全局环境中的this
无论是否处于严格模式,在全局环境中(或者理解为在任何函数体的外部)this
都指代全局对象:
console.log(this); //全局对象var num = 100;console.log(this.num); // 100
函数内部中的this
在全局环境中调用函数,函数内部的this
指向有以下两种情况:
在非严格模式下,this
的值等于全局对象:
function temp(){ return this;};console.log(temp()); //全局对象
在严格模式下,由于this
并没有被提前定义,所以,this
的值等于undefined
:
function temp(){ "use strict"; return this;};console.log(temp()); //undefined
用apply和call方法可以指定this
的值:
var obj = { name: 'Tom'};function temp(){ "use strict"; return this;};console.log(temp.call(obj)); //{name: "Tom"}
补充知识点:在严格模式下,通过this
传递给一个函数的值不会被强制转换为一个对象:
function temp(){ "use strict"; return this}console.log(temp.call(true)); // trueconsole.log(temp.call(56)); // 56console.log(temp.apply(null)); //
ES6箭头函数中的this
箭头函数不会创建自己的this
,它只会从自己所处的作用域链的上一层继承this
。
例1:箭头函数没有自己的this
指针,通过call或apply方法调用一个箭头函数时,为this
绑定特定的值是无效的:
var name = 'window';var obj = { name: 'Tom'};var temp = () => { return this.name;};console.log(temp.call(obj)); //window
箭头函数是在全局环境中调用的,它上一层的this
指向全局对象,所以,它的this
也指向全局对象。
例2:在函数内部创建的箭头函数,其this
指向等同于包含函数的this
指向:
name = 'window';let obj = { name: 'Tom', test: function(){ let temp = (()=>{ return this.name; }); return temp; }};console.log(obj.test()()); //Tom
包含函数作为对象里面的方法被调用时,它的this
指向调用它的对象obj,所以,箭头函数的this
也指向obj。
name = 'window';let obj = { name: 'Tom', test: function(){ let temp = (()=>{ return this.name; }); return temp; }};let a = obj.test;console.log(a()()); //window
包含函数被赋值给一个全局变量,之后再在全局环境中调用,显然,此时它的this
指向调用它的全局对象,所以,箭头函数的this
也指向全局对象。
例3:明白了箭头函数的this
指向原理,在回调函数中就不用写这样的代码了:var that = this,这里以setTimeout的回调函数为例:
不用箭头函数:
var name = "outer";var obj = { name: 'Tom'};function temp(){ let that = this; setTimeout(function(){ console.log(that.name); },1000);}temp.call(obj); //Tom
使用箭头函数:
var name = "outer";var obj = { name: 'Tom'};function temp(){ setTimeout(() => { console.log(this.name); },1000);}temp.call(obj); // Tom
作为对象的方法中的this
对象中函数的this指向调用函数的那个对象, 并且是离得最近的那个对象:
name = 'window';let obj1 = { name: '1', test: function(){ return this.name; }, other: { name: '2' }};obj1.other.test = obj1.test;console.log(obj1.test()); // 1console.log(obj1.other.test()); //2let aa = obj1.test;console.log(aa()); //全局对象
构造函数中的this
构造函数中的this指向创建的新对象:
function Person(name){ this.name = name;};let child = new Person('Tom');
补充知识点:new的过程到底发生了什么:
- 创建一个新的对象child;
- 将构造函数的作用域赋给对象,即构造函数中的this指向child;
- 执行构造函数中的操作;
- 返回对象child({name: "Tom"})。
内联函数中的this
指向事件发生的DOM元素:
// 在弹出框中显示:btn
Dom事件处理函数中的this
当一个函数被用作事件处理函数时,它的this
指向触发事件的元素: