侃侃JavaScript中的this

this为何如此多变?

this总是跟它的执行上下文有关,而在JavaScript总会有开辟新的执行上下文的东西,比如函数,所以,this才如此的变化。

执行环境对JavaScript中的this有影响吗?

JavaScript是一门解释型语言,需要有一个执行环境去执行它,通常的执行环境是浏览器,还有node脚本,还有`REPL`(“读取-求值-输出”循环(Read-Eval-Print Loop,简称REPL))。

如果对REPL有兴趣的话,博客中的另一篇文章介绍了`REPL`

this默认指代谁?

在不同的执行环境中,会指代不同的对象

浏览器中:

> this              // Window {top: Window, window: Window,...

> this === window   //true

> var a = 1;        //在全局中,用var声明变量,会默认给window添加

> this.a   // 1

> window.a // 1

> b = 1;            //不使用var声明变量,会默认给全局的this添加属性> this.b   // 1

> window.b // 1

在node脚本中

console.log(this);              //{}
console.log(this === global); //false console.log(this === window); //ReferenceError: window is not defined
var a = 1; //在全局中,使用var声明变量,未给global添加属性
console.log(this.a); //undefined console.log(global.a); //undefined console.log(window.a); //ReferenceError: window is not defined b = 1; //不使用var声明变量,会默认给全局的global添加属性。
console.log(this.b); //undefined console.log(global.b); // 1
在node脚本中,this默认指向一个空对象,并不是指向global,也不是指向window。

在REPL中

> this

{ DTRACE_NET_SERVER_CONNECTION: [Function],
DTRACE_NET_STREAM_END: [Function],
...
> global === this //true > var a = 1; //在全局中,使用var声明变量,会默认给全局的global添加属性 > this.a // 1 > global.a // 1 > b = 1; //不使用var声明变量,会默认给全局的this添加属性 > this.b // 1 > global.b // 1

实例扩展

我们对于省略var的变量声明方式,我们总说它是不安全的,但是是合法的。

为什么不安全?

如上文所述:不使用var声明变量,会让变量默认的添加到了全局的this中,这有时候会莫名的给变量提升它的作用域,从而影响其他全局变量。

举个栗子:

var position = "outer";           //this.position = "outer"

function test(){
position = "inner"; //this.position = "inner",在函数执行后,覆盖原先的值
console.log(this.position);
} test();

我们在外部定义了一个名为position的全局变量,它会被默认添加到全局this的属性上。

然后在我们的test函数中,又定义了一个同名的变量,但是注意,函数中的变量声明没有用var。

因为我们并没有对函数实例化,所以this.position的this会默认指代全局。

而当我们调用函数test时,函数会生成一个执行上下文,而内部position会将作用域从函数内部提升到全局,从而覆盖(污染)了外部全局定义的position变量。

所以,在JavaScript的严格模式中,是不允许省略var来声明变量的。故在声明变量的时候,就顺手加上var吧。

总结

  • this在不同的执行环境中的默认指代

  • 通过省略var声明变量导致“变量提升”现象的发生及预防

JavaScript - this详解 (一)的更多相关文章

  1. JavaScript事件详解-jQuery的事件实现(三)

    正文 本文所涉及到的jQuery版本是3.1.1,可以在压缩包中找到event模块.该篇算是阅读笔记,jQuery代码太长.... Dean Edward的addEvent.js 相对于zepto的e ...

  2. JavaScript事件详解-Zepto的事件实现(二)【新增fastclick阅读笔记】

    正文 作者打字速度实在不咋地,源码部分就用图片代替了,都是截图,本文讲解的Zepto版本是1.2.0,在该版本中的event模块与1.1.6基本一致.此文的fastclick理解上在看过博客园各个大神 ...

  3. JavaScript正则表达式详解(一)正则表达式入门

    JavaScript正则表达式是很多JavaScript开发人员比较头疼的事情,也很多人不愿意学习,只是必要的时候上网查一下就可以啦~本文中详细的把JavaScript正则表达式的用法进行了列表,希望 ...

  4. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  5. JavaScript事件详解-zepto的事件实现

    zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...

  6. javascript 函数详解2 -- arguments

    今天我们接着上篇文章来继续javascript函数这个主题.今天要讲的是函数对像中一个很重要的属性--arguments. 相关阅读: javascript 函数详解1 -- 概述 javascrip ...

  7. [原创]JavaScript继承详解

    原文链接:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html 面向对象与基于对象 几乎每个开发人员都有面向对象语言(比如C++. ...

  8. javaScript基础详解(1)

    javaScript基础详解 首先讲javaScript的摆放位置:<script> 与 </script> 可以放在head和body之间,也可以body中或者head中 J ...

  9. javascript设计模式详解之命令模式

    每种设计模式的出现都是为了弥补语言在某方面的不足,解决特定环境下的问题.思想是相通的.只不过不同的设计语言有其特定的实现.对javascript这种动态语言来说,弱类型的特性,与生俱来的多态性,导致某 ...

  10. javascript设计模式详解之策略模式

    接上篇命令模式来继续看下js设计模式中另一种常用的模式,策略模式.策略模式也是js开发中常用的一种实例,不要被这么略显深邃的名字给迷惑了.接下来我们慢慢看一下. 一.基本概念与使用场景: 基本概念:定 ...

随机推荐

  1. 六、配置github的pull request触发jenkins自动构建

    之前的配置,都是向master分支push操作触发jenkins进行构建,但是在一般的正常工作中,不会允许程序员直接向主分支推送代码:正常都是fork一个本地的分支,在本地分支调试完后,向主干分支提交 ...

  2. vs2012应用程序的打包和图标设置

    最近用VS2010+QT做了一个小软件,为了把它打包发布,查了很多资料,现在总结下,便于以后查看. 本方法不限于VS2010,也不限于QT,只要你运行你的代码得到exe之后,都可以参照本方法进行. 参 ...

  3. 关于1.0.0版Backbone.js调用validate

    网上的调用这个方法的例子都是老版本的,新版本的调用方法有所变化,首先错误绑定事件error换成了invalid,其次设置数据时应传入{validate: true} var Chapter = Bac ...

  4. JSP显示错误信息中四个范围来保存变量

    JSP中提供了四个范围来保存变量,分别是page,request,session,以及application 其中page范围只在当前页面有效,离开当前页面就失效了,这个肯定不行 request范围在 ...

  5. ssm框架整合之Spring4+SpringMVC+Mybaties3之配置文件如何配置及内容解释--可直接拷贝使用--不定时更改之2017/4/29

    经测试,需注意以下几点: 1,controller的自动扫描不能放在applicationContext.xml中,要放在spring-mvc.xml中.同样是<context:componen ...

  6. java使用POI进行Excel读写

    1 jar包下载 参考链接:http://www.cnblogs.com/gmq/archive/0001/01/01/1521496.html poi-3.7-20101029.jar和源码下载地址 ...

  7. spring中bean 的属性id与name

  8. solr自动提示 - jquery ui autocomplete

    需求: 搜索框中 输入部分关键词之后,有下拉联想提示.选中提示,使用鼠标或者使用enter键,则触发搜索功能.没有选择搜索提示,使用部分输入关键词作为搜索,直接使用enter键也能触发搜索功能.整个过 ...

  9. 16-多线程爬取糗事百科(python+Tread)

    https://www.cnblogs.com/alamZ/p/7414020.html   课件内容 #_*_ coding: utf-8 _*_ ''' Created on 2018年7月17日 ...

  10. C#中一个窗口是一个类呢,还是一个窗口类的实例呢?(转)

    C#中一个窗口是一个类呢,还是一个窗口类的实例呢? 答: 没有一个人说到重点上. 一个窗口,它不是仅仅用一个类可以描述的: 首先,这个窗口的数据类型类型,是从Form类派生下来的,也就是说它的定义是一 ...