资讯专栏INFORMATION COLUMN

JavaScript中的this

tain335 / 3286人阅读

之前关注了一个公众号: JavaScript,里面详细描述了this的各种情况,在此总结一下.
只考虑当宿主环境是浏览器的时候,并且处于非严格模式下:
this是在运行时绑定的,并不是在编写时绑定的,this的绑定只取决于函数的调用方式.
在全局范围内,this等价于window对象。

</>复制代码

  1. console.log(this === window); //true

在全局范围内,用var声明一个变量和给this或者window添加属性是等价的。

</>复制代码

  1. var foo = "bar";
  2. console.log(foo); //"bar"
  3. console.log(window.foo); //"bar"
  4. console.log(this.foo); //"bar"

在全局范围内,直接给一个变量赋值(不用var声明)和给this或者window添加属性(也可能是改变属性值)是等价的。

</>复制代码

  1. //添加
  2. foo = "bar";
  3. console.log(foo); //"bar"
  4. console.log(window.foo); //"bar"
  5. console.log(this.foo); //"bar"
  6. //改变
  7. foo = "bar";
  8. function changeFoo() {
  9. foo = "foo"; //因为在函数内没有用var定义foo,所以此时的foo和上面的foo是同一个变量
  10. }
  11. console.log(this.foo); //"bar"
  12. changeFoo();
  13. console.log(this.foo); //"foo"

普通函数调用

</>复制代码

  1. foo = "bar";
  2. function changeFoo() {
  3. this.foo = "foo";
  4. }
  5. console.log(this.foo); //"bar"
  6. changeFoo();
  7. console.log(this.foo); //"foo"

new调用

</>复制代码

  1. foo = "bar";
  2. function changeFoo() {
  3. this.foo = "foo";
  4. }
  5. console.log(this.foo); //"bar"
  6. console.log(new changeFoo().foo); //"foo"
  7. console.log(this.foo); //"bar"
  8. function Thing() {
  9. console.log(this); // 此时的this是一个新创建的空对象,即{},并且{}.__proto__ === Thing.prototype
  10. console.log(this.foo); //该对象没有自有属性,会去访问this.__proto__上的foo属性
  11. }
  12. Thing.prototype.foo = "bar";
  13. var thing = new Thing(); //"bar"
  14. console.log(thing.foo); //"bar"

当作对象的方法调用

</>复制代码

  1. var obj = {
  2. name: "irene",
  3. getName: function() {
  4. console.log(this.name);
  5. }
  6. }
  7. obj.getName(); //"irene".此时this指向对象obj
  8. 简单坑:
  9. var getName = obj.getName;
  10. getName(); // undefined.此时是普通函数调用,this指向全局对象window
  11. 高级坑:
  12. var obj2 = {
  13. name: "irene2"
  14. }
  15. (obj2.getName = obj.getName)(); // undefined.此时复制操作的返回值是function() {console,.log(this.name);},然后调用这个函数,又是普通函数调用的情况,所以this指向全局对象window.
  16. 高级坑:
  17. var obj = {
  18. name: "irene",
  19. foo: function() {
  20. console.log(this);
  21. }
  22. foo2: function() {
  23. console.log(this);
  24. setTimeout(function(){
  25. console.log(this);
  26. }, 1000);
  27. }
  28. };
  29. obj.foo(); //指向obj,属于当作对象的方法调用的情况
  30. obj.foo2(); //第一个this指向obj,和上面的情况一致,1s之后,输出的this指向全局对象,属于普通函数调用的情况.这是为何???

我个人的理解是酱紫的:JS只有一个线程,称为主线程.先执行主线程中执行栈里的代码,当主线程执行栈为空时,才会进行事件循环来查看是否有待处理事件,当事件循环检测到任务队列中有事件就取出相关回调放入执行栈中,由主线程执行.setTimeout的第一个函数参数function() {console.log(this);}会被添加到了任务队列中.当obj.foo2();执行完之后(即主线程执行栈为空),取出任务队列中的function() {console.log(this);}放入执行栈中,然后执行.此时的执行环境是全局环境,所以this指向全局对象window.关于JS的线程/事件循环/任务队列可以参考http://www.cnblogs.com/3body/...

</>复制代码

  1. 简单坑:
  2. var personA = {
  3. name: "xl",
  4. showName: function() {
  5. console.log(this.name);
  6. }
  7. };
  8. var personB = {
  9. name: "xll",
  10. getName: personA
  11. };
  12. var personC = {
  13. name: "xll",
  14. getName: personA.showName
  15. };
  16. personB.getName.showName(); //"xl"
  17. personC.getName(); //"xll"
  18. 简单坑:
  19. var name = "jay";
  20. var person = {
  21. name: "irene",
  22. getName: function() {
  23. return function() {
  24. return this.name;
  25. }
  26. }
  27. };
  28. console.log(person.getName()()); //"jay"
  29. 简单坑:
  30. function a() {
  31. var t = "r";
  32. function b() {
  33. console.log(this);
  34. console.log(t);
  35. }
  36. b();
  37. return b;
  38. }
  39. a(); //普通函数调用,所以this指向全局对象window

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81878.html

相关文章

  • JavaScript深入浅出

    摘要:理解的函数基础要搞好深入浅出原型使用原型模型,虽然这经常被当作缺点提及,但是只要善于运用,其实基于原型的继承模型比传统的类继承还要强大。中文指南基本操作指南二继续熟悉的几对方法,包括,,。商业转载请联系作者获得授权,非商业转载请注明出处。 怎样使用 this 因为本人属于伪前端,因此文中只看懂了 8 成左右,希望能够给大家带来帮助....(据说是阿里的前端妹子写的) this 的值到底...

    blair 评论0 收藏0
  • 学习React之前你需要知道的的JavaScript基础知识

    摘要:和类在开始时遇到类组件,只是需要有关类的基础。毕竟,中的条件呈现仅再次显示大多数是而不是特定的任何内容。 在我的研讨会期间,更多的材料是关于JavaScript而不是React。其中大部分归结为JavaScript ES6以及功能和语法,但也包括三元运算符,语言中的简写版本,此对象,JavaScript内置函数(map,reduce,filter)或更常识性的概念,如:可组合性,可重用...

    bitkylin 评论0 收藏0
  • JavaScript中的面向对象(object-oriented)编程

    摘要:对象在中,除了数字字符串布尔值这几个简单类型外,其他的都是对象。那么在函数对象中,这两个属性的有什么区别呢表示该函数对象的原型表示使用来执行该函数时这种函数一般成为构造函数,后面会讲解,新创建的对象的原型。这时的函数通常称为构造函数。。 本文原发于我的个人博客,经多次修改后发到sf上。本文仍在不断修改中,最新版请访问个人博客。 最近工作一直在用nodejs做开发,有了nodejs,...

    JerryZou 评论0 收藏0
  • JavaScript进阶之’this

    摘要:所以相同点是,在全局范围内,全局变量终究是属于老大的。只生效一次引入了。只生效一次在箭头函数中,与封闭词法环境的保持一致。我通常把这些原始函数叫做构造函数。在里面你可以嵌套函数,也就是你可以在函数里面定义函数。 showImg(https://img-blog.csdnimg.cn/20190522000008399.jpg?x-oss-process=image/watermark,...

    shenhualong 评论0 收藏0
  • 理解 JavaScript 中的 this 关键字

    摘要:原文许多人被中的关键字给困扰住了,我想混乱的根源来自人们理所当然地认为中的应该像中的或中的一样工作。尽管有点难理解,但它的原理并不神秘。在浏览器中,全局对象是对象。运算符创建一个新对象并且设置函数中的指向调用函数的新对象。 原文:Understanding the this keyword in JavaScript 许多人被JavaScript中的this关键字给困扰住了,我想混乱的...

    jayzou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<