1.全局上下文中 this

  1. /*
  2. 1.全局上下文中的 this
  3.  
  4. node环境下:
  5.  
  6. 严格模式下: {} {} 报错
  7.  
  8. 非严格模式下:{} {} {}
  9. */
  10.  
  11. 'use strict'; // 严格模式
  12.  
  13. // demo 1:
  14. console.log(this); // {}
  15.  
  16. // demo 2:
  17. var a = this;
  18. console.log(a); // {}
  19. var b = 1;
  20. console.log(global.b); // undefined
  21.  
  22. // demo 3:
  23. b = this; // 注意:严格模式下,变量必须得声明;非严格模式,可以省略声明符
  24. console.log(b); // {}
  25. c = 1;
  26. console.log(global.c); //
  27.  
  28. /*
  29. 分析:
  30.  
  31. node环境下:
  32.  
  33. node环境下 的上下文组成 与 浏览器环境下 有些不同;
  34.  
  35. 扩展了解一下,Node.js的全局对象 global:
  36.  
  37. 定义:Node.js中的全局对象是 global, 所有全局变量(除了 global 本身以外)都是global对象的属性;
  38.  
  39. 在 Node.js 中,我们可以直接访问到 global属性,而不需要在应用中包含它;
  40.  
  41. 也就是说,global 是全局对象,但是它还是 global.global的属性值,这是递归的过程;
  42.  
  43. 这跟浏览器下的 window对象 是一个逻辑,window对象还是 window.window 的属性值;
  44.  
  45. 全局对象 与 全局变量的关系:
  46.  
  47. global的根本作用是作为全局变量的宿主,按照 ECMAScript的定义,满足以下条件的变量为全局变量:
  48.  
  49. 1.在最外层定义的变量
  50.  
  51. 2.全局对象的属性
  52.  
  53. 3.隐式定义的变量(未定义直接赋值的变量)
  54.  
  55. 当你定义一个全局变量时,这个变量同时也会成为全局对象的属性,反之亦然。需要注意的是,在 Node.js中你不可能在最外层定义变量,
  56.  
  57. 因为所有用户代码都是属于当前模块的,而模块本身不是最外层上下文。
  58.  
  59. 注意:永远使用 var 定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。
  60.  
  61. 所以,以上三个demo 获取 this 的方式:
  62.  
  63. demo 1: 直接获取 this, 实际上 demo 1 创建执行上下文的过程是在 当前模块中进行的,所以说这个模块的上下文环境才是,demo 1 代码执行时的执行上下文,
  64.  
  65. 也就是说 环境对象是当前模块对象,而这个模块对象是个 新对象{},而结果输出 {}, 也就符合“this 指向其执行上下文的环境对象”这一结论了;
  66.  
  67. demo 2: 根据定义,由于用var 声明的变量,实际上并不是在最外层上下文中声明的变量,是在当前模块声明的变量(global.b 值为 undefined,已经证明这点了),
  68.  
  69. 但是,整个代码的执行过程还是在 当前模块的上下文中进行的,同上 输出 {},也就符合“this 指向其执行上下文的环境对象”这一结论;
  70.  
  71. demo 3: 可以看出 demo 3 在非严格模式下隐式定义了一个变量,并且给它赋了值,根据全局变量的定义,这样隐式定义变量的方式,
  72.  
  73. 实际上是在全局对象上定义一个属性,也称为全局变量,所以 通过 global对象可以获取到(global.c 的值为 1,已证明这点);
  74.  
  75. 但是要弄清楚,在这个全局变量的 定义过程,还是在 当前模块进行的,所以 此时 this指向依然是 当前模块的执行上下文对象 {};
  76.  
  77. 所以,“this 指向其执行上下文的环境对象” 这一结论依然成立;
  78.  
  79. 总结:
  80.  
  81. Node环境下:
  82.  
  83. 全局的执行上下文 进行的过程是在 当前模块下进行的,所以全局执行上下文的环境对象是当前模块{},所以全局中 this 指向当前模块对象{};
  84. */

2.函数上下文的 this

  1. /*
  2. 2.函数上下文中的 this
  3.  
  4. Node环境下:
  5.  
  6. 严格模式下: this 指向被指定的环境对象,即使指定的是 null 或者 undefined;
  7.  
  8. 非严格模式下:this 指向被指定的环境对象,如果指定的是 null 或者 undefined,会转为全局对象 global对象;
  9. */
  10.  
  11. "use strict"
  12.  
  13. // demo 1:
  14. function aa(){
  15. console.log(this);
  16. }
  17.  
  18. aa(); // 作为单独函数执行(没有指定 环境对象):strict-->"undefined" nostrict-->"global"
  19.  
  20. // demo 2:
  21. var obj = {
  22. a: 1,
  23. b: function(){
  24. console.log(this);
  25. }
  26. }
  27.  
  28. obj.b(); // 作为对象方法执行: strict-->obj nostrict-->obj
  29.  
  30. // demo 3:
  31. aa.call(obj); // 作为单独函数执行(指定 环境对象为 obj): strict-->obj nostrict-->obj
  32.  
  33. // demo 4:
  34. aa.call(null); // 作为单独函数执行(指定 环境对象为 null):strict-->null nostrict-->global
  35.  
  36. // demo 5:
  37. aa.call(undefined); //作为单独函数执行(指定 环境对象为 undefined):strict-->undefined nostrict-->global
  38.  
  39. /*
  40. 总结:函数上下文中的 this
  41.  
  42. Node环境 严格模式下:
  43.  
  44. 函数作为单独函数 执行:
  45.  
  46. 1.函数执行上下文的环境对象 是指定的,指定什么就是什么;this指向这个指定的环境对象;即使指定的是 null 或者 undefined;
  47.  
  48. 函数作为对象方法 执行:
  49.  
  50. 2.这个函数执行上下文的环境对象就是这个拥有它的对象;this指向这个拥有它的对象;
  51.  
  52. Node环境 非严格模式下:
  53.  
  54. 函数作为单独函数 执行:
  55.  
  56. 1.函数执行上下文的环境对象 是指定的,指定什么就是什么;this指向这个指定的环境对象,如果指定的是 null 或者 undefined,会转为全局对象 global对象;
  57.  
  58. 函数作为对象方法 执行:
  59.  
  60. 2.这个函数执行上下文的环境对象就是这个拥有它的对象;this指向这个拥有它的对象;
  61. */

3.对象属性中的 this

  1. /*
  2. 3.对象属性中的 this
  3.  
  4. 注意:这里指的是如下的形式,不要把它和 对象方法中的 this搞混;对象方法中的 this,要规划到 函数上下文的 this中;
  5.  
  6. Node环境下:
  7.  
  8. 严格模式下:{}
  9.  
  10. 非严格模式下: {}
  11. */
  12. 'use strict'
  13. var obj = {
  14. a: 1,
  15. b: 2,
  16. c: this,
  17. sayHi: function(){
  18. console.log('Hi');
  19. }
  20. }
  21.  
  22. console.log(obj.c); // {}
  23.  
  24. /*
  25. 分析:
  26.  
  27. 其实,这样的对象字面量的形式,可能看起来会有些困惑,我们可以变形来分析;因为对象字面量的形式,实际上是由如下的形式简化而来的写法;
  28.  
  29. var obj = new Object();
  30. obj.a =1;
  31. obj.b = 2;
  32. obj.c = this;
  33. obj.sayHi = function(){
  34. console.log('Hi');
  35. }
  36.  
  37. 这样看来就清晰很多了,上边这段代码执行的时候,不就是把全局执行上下文的环境对象赋给 obj.c 属性吗,关于 Node中全局上下文的环境对象 为 一个新对象{},我们已经介绍过了;
  38.  
  39. 而且结果,也正符合我们此时所得出的结果;
  40.  
  41. 所以,这样作为对象中的 this,可以规到全局执行上下文中的 this 一类中,this 指向 全局执行上下文的环境对象{};
  42. */
  43. /*
  44. 一个例子,可能没有什么说服力,我们再来个嵌套形式的 来证实我们的结论, 如下:
  45. */
  46. var o1 = {
  47. a: 1,
  48. b: this,
  49. o2: {
  50. a: 1,
  51. b: this
  52. }
  53. }
  54.  
  55. console.log(o1.o2.b); // {}
  56. /*
  57. 结果依然是 {}, 其实 如上的形式,可以变形为:
  58.  
  59. var o1 = new Object();
  60. o1.a = 1,
  61. o1.b = this;
  62. o1.o2 = new Object();
  63. o1.o2.a = 1;
  64. o1.o2.b = this;
  65.  
  66. 上面这段代码 在执行时,它的执行上下文的环境对象依然是 全局上下文的环境对象;所以说 this依然指向 {};
  67.  
  68. */
  69.  
  70. /*
  71. 概括:对象属性中的 this指向为 全局执行上下文的环境对象{};
  72. */

4.构造函数 和 原型方法中的 this

  1. /*
  2. 4.构造函数 和 原型方法中的 this
  3.  
  4. 浏览器环境下:
  5.  
  6. 严格模式下:以构造函数名命名的新对象
  7.  
  8. 非严格模式下: 以构造函数名命名的新对象
  9. */
  10. "use strict"
  11.  
  12. function Person(){
  13.  
  14. console.log(this); // Person {}
  15.  
  16. this.name = 'jack';
  17.  
  18. console.log(this); // Person {name: "jack"}
  19. }
  20.  
  21. Person.prototype.sayThis = function(){
  22. console.log(this);
  23. }
  24.  
  25. Person.prototype.sayThis(); // {sayThis: ƒ}
  26.  
  27. new Person(); // Person {} --> // Person {name: "jack"}
  28.  
  29. /*
  30. 分析 1:
  31.  
  32. 构造函数与普通函数的最重要的不同之处,就是构造函数可通过 new操作符,创造实例;
  33.  
  34. 那么在利用构造函数创造实例的过程到底发生了什么呢? 其实呢,是要经历以下几个过程的:
  35.  
  36. 1.创造一个 新对象,作为执行上下文的环境对象;(注意:这里为什么说成是新对象,而不说成是空对象呢,因为 function默认是有 prototype属性存在的,它指向原型对象)
  37.  
  38. 2.构造函数开始执行,它的执行上下文环境对象就为这个新对象,也就是说 this指向这个新对象;
  39.  
  40. 3.利用 this来给这个新对象赋值;
  41.  
  42. 4.返回这个被赋值之后的 新对象;
  43.  
  44. 通过上面 new Person() 执行后输出的结果来看,确实是这样的一个过程;没有没给 this赋值前输出的是 Person{}, 赋值后,输出的 Person{name:'jack'};
  45.  
  46. 所以 概括:
  47.  
  48. 构造函数中的执行上下文的环境对象为,以构造函数名命名的新对象;
  49.  
  50. 分析 2:
  51.  
  52. 至于原型方法中 this, 其实,在我们了解了 “函数上下文的 this” 之后,应该很清楚了,它指向给它指定的环境对象,也就是确定了的 构造函数的原型对象;
  53.  
  54. 所以,Person.prototype.sayThis() 执行后,输出的结果是 Person构造函数的原型对象 --> Person.prototype 对象;
  55. */

5.应用 call、apply、bind 方法后的 this

  1. /*
  2. 5.应用 call、apply、bind 方法后的 this
  3.  
  4. 了解:call、apply、bind 这三个方法是 Function对象才有的方法;它们的作用,主要是指定函数中 this中的指向,只是用法稍有不同;
  5.  
  6. 浏览器环境下:
  7.  
  8. 严格模式下:this指向 这三个方法所指定的这个值,无论是什么,即使是 null、undefined, this 也指向它们;
  9.  
  10. 非严格模式下:this指向 这三个方法所指定的这个值,null 和 undefined 值会被转换为全局对象 window;
  11.  
  12. */
  13.  
  14. "use strict"
  15.  
  16. // demo 1:
  17. var o1 = {
  18. a: 11,
  19. b: 12,
  20. sayA: function(){
  21. console.log(this.a);
  22. }
  23. }
  24.  
  25. var o2 = {
  26. a: 21,
  27. b: 22
  28. }
  29.  
  30. o1.sayA.call(o2); //
  31.  
  32. // demo 2:
  33. function sayB(){
  34. console.log(this.b);
  35. }
  36.  
  37. sayB.call(o2); //
  38. sayB.apply(o2); //
  39.  
  40. var bSayB = sayB.bind(o2);
  41. bSayB(); //
  42.  
  43. /*
  44. 其实这块不应该单提出来一个作总结分析的,完全可以规划到“函数上下文的 this”中去,只是在我们平时 coding的时候,
  45.  
  46. 这三个方法是经常要用到的 所以单拿出来,以作记忆吧;
  47.  
  48. */

原创:转载注明出处,谢谢 :)

this指向 - Node环境的更多相关文章

  1. node环境配置安装(nvm)

    在我们前端开发工程中,很多繁琐机械的操作都是会慢慢的被抽离出来的,当我们为dom操作和浏览器兼容性感到厌烦时,jQuery出现了,当我们不想再去理会dom的添加删除等的时候,angularJS来解救我 ...

  2. node环境和浏览器的区别

    一.全局环境下this的指向 在node中this指向global而在浏览器中this指向window,这就是为什么underscore中一上来就定义了一 root: 1 var root = typ ...

  3. linux CentOs 7.4 64位 系统下 nuxt部署 、nginx 安装、node环境及软连接,pm2软连接

    一.nginx安装 1.安装依赖包 //一键安装上面四个依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 2 ...

  4. 什么是Node?Node环境配置

     什么是Node? Node.js 不是JS文件也不是一个JS框架,而是一个Server side JavaScript runtime(服务端的一个JS运行时),我们可以Node环境中运行JS代码 ...

  5. D3.js部署node环境开发

    总结一段D3.js部署node环境的安装过程 准备阶段: 首先电脑上要安装node环境,这个阶段过滤掉,如果node环境都不会装,那就别玩基于node环境搞的其他东西了. 搭建环境: 我在自己的F:系 ...

  6. win8 系统安装node环境记录

    原先我是用win7环境安装node很方便,到了win8系统突然变了,让我顿时困惑了一段时间,但还是被我找到方式解决了,记录一下解决方案: 首先在网上看了一些资料说win8下安装node环境会出错,但我 ...

  7. Linux下配置Node环境变量及问题详解

    这是之前在Linux下配置Node环境变量时踩过的坑,今天又有小伙伴询问这个问题,因此记录下来,不仅是给新童鞋们一些参考,也方便日后查阅 在这之前,相信都已经安装好了,没安装的可以查看博主另一篇文章 ...

  8. Node.js(window)基础(2)——node环境下的模块,模块间调用

    参考:http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/00143450241959 ...

  9. Node 环境变量 process.env.NODE_ENV 之webpack应用

    转载来源:https://github.com/wfzong/NODE_ENV_TEST,这里还有源码可以学习,谢谢原作者的分享! 对于process.env.NODE_ENV困惑起因为在配置webp ...

随机推荐

  1. Python 流程控制:for

    for 循环用于对一个序列进行遍历,用法如下: In [4]: for i in 'abcd': ...: print(i) ...: a b c d In [13]: for i in range( ...

  2. 多进程模块:multiprocessing

    多进程: (1) 前面我们学习的多线程,其实算不上真正的多线程,即使你开了很多个线程,在同一时间内只能有一个CPU核数来处理一个线程(2) 在 python 中,多进程算得上是真正的多线程,假设你的C ...

  3. 子Fragment获取父Fragment

    在子Fragment操作父Fragment的思路 ((FragmentRecyclerBD)FragmentAppointmentBD.this.getParentFragment()).change ...

  4. DiscuzX的目录权限设置1

    经常有朋友遇到Discuz目录权限设置出错的问题,网上千奇百怪的教程非常多,所谓的终极安全的教程更是满天飞,各种所谓的安全加强软件也随处可见,可实际过程中发现,老手用不上,新手则只会因为这些东西徒增麻 ...

  5. 使用area标签实现标签的嵌套

    在项目中我们会碰到这种需求:即点击这个整个a标签跳转到一个页面,点击a里面的某个a再跳转到另一个页面.有人会说,这还不简单,直接a标签嵌套a标签,可是事实如此吗,看代码: <a href=&qu ...

  6. 鼠标聚焦到Input输入框时,按回车键刷新页面原因及解决方法

    参考地址:http://blog.csdn.net/xuezhongsong/article/details/6859037 方式1:全局控制回车,13-回车键,27-ESC,113-F2 docum ...

  7. PHP中str_replace和substr_replace有什么区别?

    两个函数的定义:(1)str_replace() 函数替换字符串中的一些字符(区分大小写). 该函数必须遵循下列规则: 如果搜索的字符串是一个数组,那么它将返回一个数组. 如果搜索的字符串是一个数组, ...

  8. <转>Logistic回归总结

    转自http://blog.csdn.net/dongtingzhizi/article/details/15962797 当我第一遍看完台大的机器学习的视频的时候,我以为我理解了逻辑回归,可后来越看 ...

  9. [置顶] Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  10. 布局的诡异bug合集+解决方法(更新中)

    1.元素内部子元素的margin的边界线基准点的问题 论如何生硬起名字!!我反正已经被自己总结的题目绕晕了... “演员”介绍: 外层父元素:蓝色边框: 内部子元素:绿色区域: 粉红色区域是元素内部绿 ...