js中的this(普通函数,箭头函数,new)

252 阅读2分钟

关于this,我们想到的就是普通函数和箭头函数的this指向问题,那么我将一一举例说明

普通函数this

普通函数的this指向调用它的对象

function myFun(){
	var name = '日月当空曌'
	console.log(this.name) // undefined
    console.log(this) // Window 对象
}

myFun() // 等价于  window.myFun()

myFun是在最外层作用域调用的,想当于 window.myFun() ,this指向调用它的对象window,所以打印是undefined

var o = {
    name:'日月当空曌',
    sayName:function(){
    	console.log(this.name)
    }
}

o.sayName() //'日月当空曌'

let sayName1 = o.sayName
sayName1() // undefined
  • 这里o.sayName() 调用函数的对象是o,this指向o,this.name 就是o.name
  • 把o.sayName() 复制给一个新的变量,这时候调用,this指向window

构造函数this

构造函数this指向

function Person(){
	this.name = '日月当空曌'
    this.age = 18
}

let person = new Person()
console.log()

使用new调用函数,this指向新的对象

至于new创建对象经历了哪里步骤,请看js对象-构造函数

箭头函数this

箭头函数的this和普通函数不同,箭头函数的this对象就是定义时所在的this对象,而不是使用时所在的对象

学习箭头函数this之前需要明白一个问题,就是setTimeout和setInterval里回调函数this指向问题。

引用mdn的解释:**由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象,严格模式下为 undefined,这和所期望的this的值是不一样的。**(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setTimeout)

箭头函数的this指向是固定不变的

function woo() {
  setTimeout(function() {
  	console.log(this)
    console.log('id:', this.id);
  }, 100);
}

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

woo.call({id:42}); //21

foo.call({ id: 42 }); // 42

我们已经知道setTimeout的参数如果是普通函数,this指向window(原因见上文),woo.call({id:42})会返回21,而箭头函数的this总是指向函数定义生效时所在的对象,意思就是this指向箭头函数父作用域的this,即foo的this,{id:42}

再看一个例子

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭头函数
  setInterval(() => this.s1++, 1000);
  // 普通函数
  setInterval(function () {
    this.s2++;
  }, 1000);
}

var timer = new Timer();

setTimeout(() => console.log('s1: ', timer.s1), 3100); // 3
setTimeout(() => console.log('s2: ', timer.s2), 3100);// 0

new Timer() Timer函数的this指向新的对象, 箭头函数的this指向父作用域的this,即新对象的this,也就是timer,而普通函数this指向window,所以 timer.s2的值不会改变

由此,可以看到箭头函数的this固定,这种特性很有利于封装回调函数

注意点

  • 箭头函数不可以当做构造函数,不能使用new
  • 没有argument对象

练习题

var Test ={
  foo:"test",
  func:function () {
    var self=this;
    console.log(this.foo);
    console.log(self.foo);
    (function () {
      console.log(this.foo); 
      console.log(self.foo);
    })();
  }
};
Test.func();

运行结果是 test test undefined test 大家可能好奇的是undefined
其中

  (function () {
      console.log(this.foo); 
      console.log(self.foo);
    })();

这是一个立即执行函数,他是自己去调用自己,this指向的是全局作用域

参考

www.cnblogs.com/pssp/p/5216… es6.ruanyifeng.com/#docs/funct…