隐藏侧边栏

this指向问题

global this

  • 在浏览器中在全局范围内var声明一个变量给this指向都是window

在node环境里

  • 如果使用repl来执行程序的话,this并不是最高级的命名空间,最高级的是global

  • 在node环境里,如果执行一个js脚本,在全局范围内,this以一个空对象开始作为最高级的命名空间,这个时候,它和global不是等价的。

  • 在node环境里,在全局范围内,如果你用REPL执行一个脚本文件,用var声明一个变量并不会和在浏览器里面一样将这个变量添加给this。

  • 但是如果你不是用REPL执行脚本文件,而是直接执行代码,结果和在浏览器里面是一样的(神坑)

  • 在node环境里,用REPL运行脚本文件的时候,如果在声明变量的时候没有使用var或者let,这个变量会自动添加到global对象,但是不会自动添加给this对象。如果是直接执行代码,则会同时添加给global和this.

    总结起来就是:

浏览器里面this是老大,它等价于window对象,如果你声明一些全局变量(不管在任何地方),这些变量都会作为this的属性。在node里面,有两种执行JavaScript代码的方式,一种是直接执行写好的JavaScript文件,另外一种是直接在里面执行一行行代码。对于直接运行一行行JavaScript代码的方式,global才是老大,this和它是等价的。在这种情况下,和浏览器比较相似,也就是声明一些全局变量会自动添加给老大global,顺带也会添加给this。但是在node里面直接脚本文件就不一样了,你声明的全局变量不会自动添加到this,但是会添加到global对象。所以相同点是,在全局范围内,全局变量终究是属于老大的。

function this

  • 无论是在浏览器环境还是node环境,除了在DOM事件处理程序里或者给出了thisArg(接下来会讲到)外,如果不是用new调用,在函数里面使用this都是指代全局范围的this。

  • 如果使用严格模式,这时候this就会变成undefined。

  • 如果你在调用函数的时候在前面使用了new,this就会变成一个新的值,和global的this脱离干系。

object this

  • 在一个对象函数里,你可以通过this来引用这个函数的其他属性,这个用new来创建一个实例是不一样的

  • 注意,没有使用new,没有使用Object.create,也没有使用函数调用创建一个对象。你也可以将对象当作一个实例将函数绑定到上面。

  • 当你用这种方式使用this的时候,并不会越出当前的对象。只有有相同直接父元素的属性才能通过this共享变量。

  • 你可以直接通过对象引用你需要的属性。

DOM event this

  • 在一个HTML DOM事件处理程序里面,this始终指向这个处理程序被所绑定到的HTML DOM节点

  • 除非你自己通过bind切换了上下文。

  • 在HTML节点的属性里面,你可以放置JavaScript代码,this指向了这个元素

override this

  • 你不能重写this,因为它是保留字。

  • 你可以通过eval来访问this 这会造成一个安全问题,除非不用eval,没有其他方式来避免这个问题

  • 在通过Function来创建一个函数的时候,同样能够访问this

with this

  • 你可以通过with来将this添加到当前的执行环境,并且读写this的属性的时候不需要通过this

jQuery this

  • 和HTML DOM元素节点的事件处理程序一样,在许多情况下JQuery的this都指向HTML元素节点。这在事件处理程序和一些方便的方法中都是管用的,比如$.each

thisArg this

  • 如果你用过underscore.js 或者lo-dash 你可能知道许多类库的方法可以通过一个叫做thisArg 的函数参数来传递实例,这个函数参数会作为this的上下文。举个例子,这适用于_.each。原生的JavaScript在ECMAScript 5的时候也允许函数传递一个thisArg参数了,比如forEach。事实上,之前阐述的bind,apply和call的使用已经给你创造了传递thisArg参数给函数的机会。这个参数将this绑定为你所传递的对象。

  •  

posted @ 2019-11-30 13:13  阴茵  阅读(452)  评论(0编辑  收藏  举报