你需要掌握的前端基础 - this

229 阅读2分钟

this

this 是函数的执行上下文的一个属性,在非严格模式下,总是指向执行上下文。 this 存在于函数中,想要理解 this,先理解作用域和作用域链

作用域和作用域链

变量和函数的作用域是指其执行环境、可被访问的范围。 作用域链是指访问变量时依次从子作用域到父作用域寻找变量形成的链条,从下至上、从里到外。

普通函数中 this 的指向

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

function explain() {
  console.log(this.name);
}
var a = { name: "aa" };
var b = { name: "bb" };
var name = "window";
explain(); // window
explain.call(a); // aa
explain.call(b); // bb

箭头函数中 this 的指向

箭头函数的 this 在声明时就已经指定了,this 继承自父函数的 this。

// example 1
var a = () => {
  var name = "inside";
  console.log(this.name);
};
var name = "outside";
a(); // outside

//  example 2
var b = {
  name: "bb",
  func: () => {
    console.log(this.name);
  },
};
var name = "outside";
b.func(); // outside

// example 3
function foo() {
  console.log("a:", this.id);
  console.log("b:", this);
  setTimeout(() => {
    console.log("c:", this.id);
    console.log("d:", this);
  }, 0);
}

var id = 21;
foo(); // a:21 b:window c:21 d:window
foo.call({ id: 42 }); // a:42 b:{id:42} c:42 d:{id:42}

自执行函数(IIFE)中 this 的指向

在非严格模式下,自执行函数的this指向window

(function () {
  console.log(this);
})(); // window

改变 this 指向的方法

  • bind 将函数绑定在目标对象上,改变函数的 this 指向
function explain() {
  console.log(this.name);
}
var a = { name: "aa" };
explain.bind(a)(); // aa
  • call 将函数绑定在目标对象上并执行,改变函数的 this 指向,参数单个传入
function explain(secondName, age) {
  console.log(this.name + "-" + secondName + "-" + age);
}
var a = { name: "aa" };
explain.call(a, "name", 18); // aa-name-18
  • apply 将函数绑定在目标对象上并执行,改变函数的 this 指向,参数以数组方式传入
function explain(arr) {
  let [secondName, age] = arr;
  console.log(this.name + "-" + secondName + "-" + age);
}
var a = { name: "aa" };
explain.call(a, ["name", 18]); // aa-name- 18

tips

  • 多次 bind 时只第一次生效
function getName() {
  console.log(this.name);
}
let a = { name: "aa" };
let b = { name: "bb" };
getName.bind(a).bind(b)(); // 'aa'
  • 代表性题型
// 字节
var length = 10;
function fn() {
    return this.length + 1;
}
var obj = {
    length: 5,
    test1: function () {
        return fn();
    }
};
obj.test2 = fn;
//下面代码输出是什么
console.log(obj.test1()) // 11
console.log(fn() === obj.test2()) // 11 === 6 => false
// 腾讯
var x  = 10;
function f1{
  console.log(x);
}
function f2(func){
  var x = 20;
  func();
}
f2(f1); // 10

学习的意义不在于你学了多少,而在于学完之后在你脑子里留下了多少。 更多知识点请关注小姐姐主页,一起努力呀!

此文章为 【前端基础】 系列文章,关注小姐姐,一起学一学!