最近在参加的几场面试中都涉及到了对于jsthis对象的理解,那么怎样去理解this呢?这里针对不同的场景通过代码来帮助我们理解好this

this到底指向什么?

this指向什么呢?一言以蔽之:

this最终指向的是那个调用它的对象

下面通过代码来分析this的指向问题。

默认绑定全局变量window

var a = 'hello';function foo() {console.log( this.a );
}foo(); // hello

这里调用foo()就相当于window.foo()。因此this引用的是window。也就是下面这句话:

如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window

隐式绑定

function foo() {console.log( this.a );
}var obj = {a: 'hello',foo: foo
};obj.foo(); // hello

这里调用foo的是obj,因此this指向的是obj对象。

再来看一个例子:

function foo() {console.log( this.a );
}
var obj2 = {a: 'hello',foo: foo
};
var obj1 = {a: 'world',obj2: obj2
};
obj1.obj2.foo(); // hello

这个例子可能看起来比较晕,那么this指向的是obj1还是obj2呢?其实关于this的引用还有一句话要记住:

如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象

理解了上面两个例子之后再看一种情况:

function foo() {console.log( this.a );
}var obj = {a: 'hello',foo: foo
};var bar = obj.foo; // 函数引用传递
var a = "Global";
bar(); // "Global"

这里this指向的是window对象,想要理解这点还需要记住一句话:

this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的

上面的例子中虽然函数foo是被对象obj所引用,但是在将foo赋值给变量bar的时候并没有执行,最终foo是由bar来执行的,而bar指向的是window对象。

显示绑定

通过bind(),apply(),call()函数可以显示的绑定this作用域,它接收的第一个参数即是上下文对象并将其赋给this。

function foo() {console.log( this.a );
}var obj = {a: 'hello'
};foo.call(obj); // hello

如果我们传递第一个值为简单值,那么后台会自动转换为对应的封装对象。如果传递为null,那么结果就是在绑定默认全局变量。看下面的例子:

function foo() {console.log( this.a );
}var obj = {a: 2
};var a = 'hello';
foo.call( null); // hello

new新对象绑定

如果是一个构造函数,那么用new来调用,那么绑定的将是新创建的对象。如:

function foo(a) {this.a = a;
}var bar = new foo('hello');
console.log(bar.a);// hello

this在闭包里的简单应用

如果已经理解了上面this的基本用法,那么我们来看一个this在闭包的指向问题:

var flag = "window";
var object = {flag : "local",sayFlag: function(){//返回一个匿名函数return function(){console.log(this.flag);}}
}
object.sayFlag()(); //window

这里的this是在一个匿名函数里面调用的,object.sayFlag()函数返回的是一个匿名函数,也就是说this应该指向的是匿名函数的执行环境,那么匿名函数的执行环境到底应该是什么呢?

匿名函数的执行环境具有全局性,this通常指向window

那么如何访问“local呢”?

var flag = "window";
var object = {flag : "local",sayFlag: function(){var that = this; //此处的this是object的引用//返回一个匿名函数return function(){alert(that.flag);}}
}
object.sayFlag()(); //local

this在es6 Class中的指向

在类的方法中this默认指向的是类的实例,但是如果单独使用这个方法,就会报错,比如:

class Printer{printName(name = 'there') {this.print(`Hello ${name}`);}print(text) {console.log(text);}
}const printer= new Printer();
const { printName } = printer;
printName(); // 报错

单独执行printName的时候,this指向的是该方法运行时的上下文环境,解决这个问题的方法有如下几个:

  1. 使用箭头函数
class Printer{printName(name = 'there') {this.print = ()=>{this.print(`Hello ${name}`);}}print(text) {console.log(text);}
}
const printer= new Printer();
const { printName } = printer;
printName(); // 报错
  1. 使用bind方法
class Printer{constructor() {this.printName = this.printName.bind(this);}printName(name = 'there') {this.print(`Hello ${name}`);}print(text) {console.log(text);}
}const printer= new Printer();
const { printName } = printer;
printName(); // 报错
  1. 将this传给一个变量
class Printer{printName(name = 'there') {const self = this;self.print(`Hello ${name}`);}print(text) {console.log(text);}
}const printer= new Printer();
const { printName } = printer;
printName();

参考链接:
https://www.cnblogs.com/pssp/p/5216085.html

下面的是我的公众号二维码图片,欢迎关注。

十分钟理解javascript中的this对象相关推荐

  1. java弱引用怎么手动释放,十分钟理解Java中的弱引用,十分钟java引用

    十分钟理解Java中的弱引用,十分钟java引用 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,帮助大家理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限 ...

  2. 【原理】理解JavaScript中的上下文-对象字面量

    ⭐️ 本文首发自 前端修罗场(点击即可加入),一个专注 Web 技术.答疑解惑.面试辅导.职业发展的社区.现在加入,即可参与打卡挑战,和一群人一起努力.挑战成功即可获取一次免费的模拟面试机会,进而评估 ...

  3. 理解javascript中的回调函数(callback)【转】

    在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...

  4. 理解JavaScript中的原型继承(2)

    两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...

  5. 选择嵌套_如何优雅地在JavaScript中访问嵌套对象

    在JavaScript中访问嵌套对象 以超酷的方式安全地访问JavaScript中的嵌套对象 JavaScript是惊人的,我们都知道.但是JavaScript中的一些东西真的很奇怪,它们让我们大开眼 ...

  6. 深入理解JavaScript中的属性和特性

    深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...

  7. 理解JavaScript中的原型与原型链

    理解JavaScript中的原型与原型链 原型链是一种机制,指的是JavaScript中每个内置的对象都有一个内置的__proto__属性指向创建它的构造函数的prototype(原型)属性.原型链的 ...

  8. 十分钟理解Transformer

    本文转载于知乎文章:十分钟理解Transformer Transformer是一个利用注意力机制来提高模型训练速度的模型.关于注意力机制可以参看这篇文章,trasnformer可以说是完全基于自注意力 ...

  9. 理解javascript中的回调函数(callback)

    理解javascript中的回调函数(callback) 在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Obje ...

最新文章

  1. 基本权限管理框架,开通淘宝支付
  2. jQuery的三种bind/One/Live事件绑定使用方法
  3. html5 ajax数据显示,html5的ajax学习(二)
  4. [react] React中你有使用过propType吗?它有什么作用?
  5. mysql临时表的的理解,如何理解存储过程中已存在的mysql临时表?
  6. 周鸿祎回应参加RSA大会一事:已在家自行隔离 目前身体状况一切都好
  7. 【es】ES RestHighLevelClient 请求报错:Connection reset by peer
  8. 怎么在html使用百度商桥,电脑版网站如何添加爱番番(原:百度商桥)
  9. Tarjan边的双联通
  10. jquery值ajaxForm
  11. 倾斜补偿的电子罗盘(1):地磁场,磁传感器,倾斜补偿
  12. 配置项目外网访问(公网IP+DDNS)
  13. Cannot open url. please check this url is correct
  14. Python学习笔记--day10函数入门
  15. 30题前端工程开发师面试题
  16. 肖特基、整流、开关、快恢复二极管的区别
  17. Zotero使用Onedrive实现云同步
  18. 机油纯粹的复合机油要选哪款了?
  19. SparkSQL join
  20. Linux(11)——LVM实验

热门文章

  1. UI设计师工作流程详解,让你充分了解UI设计师
  2. springboot使用华为OBS上传下载文件详解
  3. 用数学归纳法证明二叉树的先序遍历序列和中序遍历序列可以唯一确定一颗二叉树
  4. RICHO 打印机驱动【急速】安装 win10/win7
  5. 泛微E-Office最新文件上传漏洞(CNVD-2021-49104)
  6. BRD、MRD 和 PRD
  7. Powershell批量修改用户的UPN后缀
  8. Linux 的带宽管理系统
  9. [Android] 免费明星艺术签名设计V3.0
  10. 2D网游短期爆发难掩颓势