您的位置 首页 java

JavaScript初学必看:this,那些我们在使用this时的陷阱!

在JS开发中,经常使用this,我觉得有必要对this进行总结一下。

定义

this 代表当前正在执行某个方法的对象,如果没有当前方法(或该方法不属于任何其它对象),则是指全局对象。也就是说,this代表调用该方法对象的引用。

全局范围中的this

全局里面的this,比较好理解,一般不容易出错。首先,看看下面代码,会输出什么呢?

<script type="text/javascript">
 console.log(this==window);
 console.log(this);</script>1234 

直接结果如下:

这说明,如果没有当前方法(或该方法不属于任何其它对象),则this是指全局对象window。

于是可以得出,输出一个 全局变量 ,可以采取下面几种方式

 var name="dqs"; console.log(name); console.log(window['name']); console.log(window.name); console.log(this['name']); console.log(this.name);1234567 

函数里面的this

函数里面的this,取决于函数的调用方式,调用方式不一样,那么里面的this也就会不一样。

直接以函数形式调用

直接以函数形式调用,函数里的this,代表全局对象,即window。

<script type="text/javascript">function fn(){
 console.log(this);
 }
fn();</script>123456 

结果如下:

以全局对象的方法形式调用

以全局对象的方法形式调用,此时this,也代表全局对象,即window。

<script type="text/javascript">function fn(){
 console.log(this);
 }
fn();
 console.log(this.fn());
 console.log(window.fn());</script>12345678 

借助call或者apply 函数调用

借助call或者apply函数调用时候,此时this代表指定的对象。

<script type="text/javascript">var obj={name:'obj_dqs'}; function fn(){
 console.log(this);
 } function fn2(){
 this.name='fn_dqs';
 }
 fn.call(obj)//此时this代表obj
 fn.call(fn2)//此时this代表fn2</script>123456789101112 

结果如下:

构造函数 形式调用

当以构造函数形式调用时候,此时this,代表创建的对象。

<script type="text/javascript">
 var name='window_dqs';  function  fn(){
 this.name='fn_dqs'; this.showName=function(){
 console.log(this.name);
 }
 console.log(this);
 } var p=new fn();</script>1234567891011 

结果如下图:

with中的this

在分析with(obj)中的this时候,我们需要分析其所在范围。如果是在函数中的this,代表obj,如果是全局范围变量中,则代表window

<script type="text/javascript">
 var name='window_dqs'; var obj={
 name:'obj_dqs',
 showName:function(){
 console.log(this);
 }}; function showName(){
 console.log(this);
 } with(obj){
 console.log(this);
 showName();
 }
 showName();</script>1234567891011121314151617181920 

输出结果如下

以上是关于javascript中this的总结,然而实际上的操作中我们会遇到非常多的问题,让我们无从下手,在这里我给大家介绍一个自己的qun,里面有很多热情的大神,更有实际操作过的老手和老师,我也会不时分享学习的资料和视频(2131 26486),填写并私聊我(落叶)直接领取。

接下来看看我们在使用JavaScript的this的时候应当知道的。内容比较多,这里列举了一类,其他几类后面会再讲,都是用几年经验总结出来的,值得学习。

global this

  • 在浏览器里,在全局范围内,this等价于window对象。

1 <script type="text/javascript">
2 console.log(this === window); //true3 </script> 
  • 在浏览器里,在全局范围内,用 var 声明一个变量和给this或者window添加属性是等价的。

1 <script type="text/javascript">
2 var foo = "bar";
3 console.log(this.foo); //logs "bar"
4 console.log(window.foo); //logs "bar"5 </script> 
  • 如果你在声明一个变量的时候没有使用var或者let(ECMAScript 6),你就是在给全局的this添加或者改变属性值。

 <script type="text/javascript">
 foo = "bar";
 function testThis() { foo = "foo"; }
 console.log(this.foo); //logs "bar"
 testThis(); console.log(this.foo); //logs "foo"11 </script> 
  • 在node环境里,如果使用REPL(Read-Eval-Print Loop,简称REPL:读取-求值-输出,是一个简单的,交互式的编程环境)来执行程序,this并不是最高级的命名空间,最高级的是global.

> this{ 
ArrayBuffer: [Function: ArrayBuffer], 
Int8Array:{
 [Function: Int8Array] BYTES_PER_ELEMENT: 1 }, 
 Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
 ...
> global === thistrue 
  • 在node环境里,如果执行一个js脚本,在全局范围内,this以一个空对象开始作为最高级的命名空间,这个时候,它和global不是等价的。

 test.js脚本内容:
console.log(this); console.log(this === global);
REPL运行脚本:
$ node test.js {} false 
  • 在node环境里,在全局范围内,如果你用REPL执行一个脚本文件,用var声明一个变量并不会和在浏览器里面一样将这个变量添加给this。

1 test.js:
2 
3 var foo = "bar";
4 console.log(this.foo);
5 
6 $ node test.js
7 undefined 
  • 但是如果你不是用REPL执行脚本文件,而是直接执行代码,结果和在浏览器里面是一样的(神坑)

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

1 test.js
2
3 foo = "bar";
4 console.log(this.foo);
5 console.log(global.foo);
6
7 $ node test.js
8 undefined
9 bar 

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

文章来源:智云一二三科技

文章标题:JavaScript初学必看:this,那些我们在使用this时的陷阱!

文章地址:https://www.zhihuclub.com/186455.shtml

关于作者: 智云科技

热门文章

网站地图