JS this

192 阅读2分钟

前言

该文章仅仅作为自己复习知识使用,侵删 🍙🍙
天气很好,bug 很少 🌞🌞

this 几大知识点

  • new
  • 显示绑定(apply、call或者bind)
  • 箭头函数
  • 隐式绑定
  • 默认绑定

new

使用new来调用一个函数,会构造一个新对象并把这个新对象绑定到调用函数中的this

function Cat(name) {
  this.name = name
}
var name = 'window'
var cat = new Cat('史莱姆')
console.log(cat.name)

// 史莱姆

显示绑定(apply、call或者bind)

使用 apply、call或者bind ,this 绑定指定的对象

function foo() {
  console.log(this.name)
}
var cat = {name: '史莱姆1号' }
var name = '史莱姆2号'

foo()
foo.call(cat)
foo.apply(cat)
foo.bind(cat)()

// 史莱姆2号
// 史莱姆1号
// 史莱姆1号
// 史莱姆1号

bind 创建了一个新的函数,需要手动调用才会执行

箭头函数

箭头函数中的this是由外层作用域来决定的,且在函数定义时出便已经绑定 this。可以通过修改外层 this 来间接改变箭头函数 this 的指向

var cat = {
  name: '史莱姆2号',
  getName1: () => {
    console.log(this.name)
  },
  getName2: function() {
    console.log(this.name)
    return () => {
      console.log(this.name)
    }
  }
}
var name = '史莱姆1号'
cat.getName1()
cat.getName2()()

// 史莱姆1号
// 史莱姆2号
// 史莱姆2号

  • obj.getName1() 外层作用域是 window。(作用域只有全局作用域和局部作用域函数)
  • cat.getName2()this 指向 cat 对象,返回的箭头函数 this 由外层作用域决定,因此打印出 史莱姆2号

隐式绑定

this 永远指向最后调用它的那个对象
当函数引用有上下文对象时(即函数作为引用属性被添加到对象中),隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象。

function getName() {
  console.log(this.name);
}

var cat = {
  name: '史莱姆1号',
  getName: getName
};

cat.getName();  

// 史莱姆1号

隐式绑定丢失

严格模式下, this 指向 undefined

绑定至上下文对象的函数被赋值给一个新的函数,然后调用这个新的函数时

function getName1() {
  console.log( this.name);
}

var cat = {
  name: '史莱姆1号',
  getName1: getName1
};

var getName2 = cat.getName1; 
var name = '史莱姆1号';
bar();  

// 史莱姆1号

传入回调函数时

function getName1() {
  console.log( this.name);
}

function getName2(fn) {
  fn();  // <-- 调用位置
}

var cat = {
  name: '史莱姆2号',
  getName1: getName1
};

var name = '史莱姆1号';
getName2( cat.getName1 ); 

// 史莱姆1号

在将函数传入语言内置的函数比如 setTimeout 时,同样会发生隐式丢失的情况

默认绑定

在非严格模式下this指向的是全局对象window,而在严格模式下会绑定到undefined。

优先级

  • new
  • 显示绑定
  • 隐式绑定
  • 默认绑定

参考/学习文章