码云笔记前端博客
Home > JavaScript > this 指向到底由谁来定

this 指向到底由谁来定

2019-09-24 分类:JavaScript 作者:码云 阅读(277)

本文共计1775个字,预计阅读时长需要5分钟。

关于 this 指向问题,网上的资料很多,面试问的也很多,似懂非懂的人也很多。

然而

有人觉得女生的心思很难猜,也就有人觉得 this 的指向问题比女生的心思更难猜。

  • 女生的心思其实很简单 —— 希望不猥琐的你用心去关注她(和帅没有很大关系,当然帅加分)。
  • this 的指向问题也不难 —— 谁调用就指向谁

到底谁是调用者

结论先行:this 的指向是谁调用就指向谁;即调用之前,this 还不知其指向。

讨论谁是调用者之前先说 this 的作用

this 是函数内部两个特殊对象之一,拥有这个对象可以改变显式传递的弊端,即可将函数定义的更加简洁和易于复用。

接下来重点讨论谁是调用者

1
2
3
4
5
6
7
8
9
10
11
12
13
var name = '码云笔记';
function consoleName()
{
    console.log(this.name);
}
var test = {
  name: 'mybj123.com',
  method: function()
{
    consoleName();
  }
};
test.method();

上面这个笔试题相信你已经有了答案,现在可以带着你刚才的思考切入下面的解释。

四种情况的调用

想知道 this 指向就需要找到调用者。有人认为调用者并不好确定,其实大体只有四种情况,我一一介绍。

1.直接调用的默认绑定, this 指向一定是全局对象(浏览器的话是 window)。在严格模式下其值会是 undefined。

2.对象调用的隐式绑定, this 指向就是这个调用的对象。

3.call()/apply() 方式的显式绑定, this 指向传入的对象。

4.new 方式的绑定规则, this 指向这个构造出的新对象。

第一种 & 第二种:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let name = '码云笔记';
function consoleName() {
    console.log(this.name);
}
let test =
{
  name: 'mybj123.com',
  method: function()
{
    console.log(this.name);   // mybj123.com
    consoleName();            // 码云笔记
  }
};
test.method();

开头题目的答案就在这里。

虽然 test.method() 的调用方式使 method 内部使用的 this 会指向 test,但实际调用的是 - 直接调用 consoleName();所以 this 的指向还是全局对象 window。

通过这个例子,你对第一种和第二种的绑定方式应该就懂了。

第三种:

1
2
3
4
5
6
7
8
9
let name = '码云笔记';
let test = {
  name: 'mybj123.com',
  method: function()
{
    console.log(this.name);
  }
};
test.method.apply(window);  // '码云笔记'

隐式绑定和显式绑定一起使用的时候,显式绑定的优先级更高

第四种:

1
2
3
4
5
6
function consoleName(name)
 {
    this.name = name;
}
let useNname = new consoleName('码云笔记');
console.log(useNname.name)      // 码云笔记

通过这个例子想必你对 new 方式中 this 的指向问题也明白了,即构造函数(consoleName)中的 this 会绑定到实例(useNname)上。

优先级

关于优先级我画了一张图直观的来说明这个问题:
this 指向到底由谁来定

箭头函数补充

箭头函数比较特殊,不受上面四条规则的约束。箭头函数的 this 根据外层函数确定。

而且箭头函数的 this 一旦被绑定,就无法改变。

思考题

以下代码输出什么,原因是什么?欢迎评论区留言。

1
2
3
4
5
6
7
8
9
10
11
12
13
function consoleName() {
    return (name) => {
        console.log(this.name);
    }
}
let testOne = {
  name: '码云笔记',
};
let testTwo = {
  name: 'mybj123.com',
};
let text = consoleName.call( testOne );
text.call( testTwo );

结束语

以上就是关于this指向谁的全部内容,希望对大家有所帮助,部分内容参考《JavaScript 高级程序设计》及《你不知道的 JavaScript》上。

「除特别注明外,本站所有文章均为码云笔记原创,转载请保留出处!」

赞(8) 打赏

觉得文章有用就打赏一下文章作者

支付宝
微信
8

觉得文章有用就打赏一下文章作者

支付宝
微信

上一篇:

下一篇:

你可能感兴趣

共有 0 条评论 - this 指向到底由谁来定

博客简介

码云笔记 mybj123.com,一个专注Web前端开发技术的博客,主要记录和总结博主在前端开发工作中常用的实战技能及前端资源分享,分享各种科普知识和实用优秀的代码,以及分享些热门的互联网资讯和福利!码云笔记有你更精彩!
更多博客详情请看关于博客

精彩评论

站点统计

  • 文章总数: 458 篇
  • 分类数目: 13 个
  • 独立页面: 8 个
  • 评论总数: 215 条
  • 链接总数: 14 个
  • 标签总数: 1011 个
  • 建站时间: 495 天
  • 访问总量: 8648087 次
  • 最近更新: 2019年10月21日