this详细用法介绍与例题试炼

this详细用法介绍与例题试炼

总结如下图:

在这里插入图片描述

注意:

全局上下文的 this 指向非常明确,不管有没有启用严格模式,都指向 window 对象

applycall 的功能完全一样,只是传参形式不一样,call 是传多个参数,apply 是只传参数集合。

function add(x, y, z) {
  return this.x + this.y + this.z;
}

const obj = {
  x: 1,
  y: 2,
  z: 3,
};

console.log(add.call(obj, 1, 2, 3)); // 输出 6
console.log(add.apply(obj, [1, 2, 3])); // 输出 6,只是传参形式不同而已

bindcallapply 的区别是,函数调用 callapply 会直接调用,而调用 bind 是创建一个新的函数,必须手动去再调用一次,才会生效。

function add(x, y, z) {
  return this.x + this.y + this.z;
}

const obj = {
  x: 1,
  y: 2,
  z: 3,
};

const add1 = add.bind(obj, 1, 2, 3); // bind 会返回一个新的函数
console.log(add1()); // 执行新的函数,输出 6

new 调用 > callapplybind 调用 > 对象上的函数调用 > 普通函数调用

例题试炼

测试题1:

const o1 = {
  text: "o1",
  fn() {
    return this.text;
  },
};

const o2 = {
  text: "o2",
  fn() {
    return o1.fn();
  },
};

const o3 = {
  text: "o3",
  fn() {
    var fn = o1.fn;
    return fn();
  },
};

console.log(o1.fn()); // ?
console.log(o2.fn()); // ?
console.log(o3.fn()); // ?

输出:

"o1";
"o1";
undefined;

原因:o1.fn() 中的 this 指向 o1 对象,所以输出的 this.text'o1'

执行 o2.fn() 等价于执行 o1.fn(),所以输出 'o1'

o3.fn() 理解起来稍微复杂一点,o3 对象中的代码等价于下面的代码:

const o3 = {
  text: "o3",
  fn() {
    return function () {
      return this.text;
    };
  },
};

console.log(o3.fn()());

所以 this 指向为 windowwindow.textundefined

测试题2:

const o1 = {
  text: "o1",
  fn() {
    return this.text;
  },
};

const o2 = {
  text: "o2",
  fn: o1.fn,
};

console.log(o1.fn()); // ?
console.log(o2.fn()); // ?

输出:

"o1";
"o2";

原因:o1.fn() 中的 this 指向 o1 对象,所以输出的 this.text'o1'

o2 对象中的代码等价于下面的代码:

const o2 = {
  text: "o2",
  fn() {
    return this.text;
  },
};

所以 this 指向为 o2 对象,所以输出的 this.text'o2'

测试题3:

var userName = "xxx";
const obj1 = {
  userName: "zhangsan",
  fn() {
    setTimeout(function () {
      console.log(this.userName); // ?
    });
  },
};

const obj2 = {
  userName: "zhangsan",
  fn() {
    setTimeout(() => {
      console.log(this.userName); // ?
    });
  },
};

obj1.fn();
obj2.fn();

输出:

"xxx";
"zhangsan";

原因:obj1 中调用的 this 是函数嵌套函数中的 this,所以指向 window,输出 window.userName'xxx'

obj2 中因为箭头函数的原因,this 指向上层作用域,所以指向对象 obj2,输出 obj2.userName'zhangsan'

测试题4:

var userName = "xxx";
const obj1 = {
  userName: "lin",
  fn() {
    return () => {
      console.log(this.userName); // ?
    };
  },
};

const obj2 = {
  userName: "lin",
  fn() {
    return () => {
      return () => {
        console.log(this.userName); // ?
      };
    };
  },
};

obj1.fn()();
obj2.fn()()();

输出:

"lin";
"lin";

原因:因为有箭头函数,嵌套多少层,最终都会一层一层地读到第一层,所以 this 指向为对象本身。

测试题5:

function foo() {
  return () => {
    console.log(this.a);
  };
}

const obj1 = {
  a: 2,
};

const obj2 = {
  a: 3,
};

const bar = foo.call(obj1); // ?
bar.call(obj2); // ?

输出:

2;

原因:foo.call(obj1) 输出 2 是因为 call 显式改变 this 指向。

bar.call(obj2) 啥也不输出,因为箭头函数的绑定无法被修改。

测试题6:

var a = 100;
const foo = () => () => {
  console.log(this.a);
};

const obj1 = {
  a: 2,
};

const obj2 = {
  a: 3,
};

const bar = foo.call(obj1); // ?
bar.call(obj2); // ?

输出:

100;

原因:foo.call(obj1) 输出 2 是因为 call 显式改变 this 指向。

bar.call(obj2) 啥也不输出,因为箭头函数的绑定无法被修改。

记住前面的判断方法,大部分的this指向你就都可以弄懂啦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值