详解javascript中的this

唯一浩哥      2022-02-07     297

关键词:

JavaScript中的this总是让人迷惑,应该是js众所周知的坑之一。 个人也觉得js中的this不是一个好的设计,由于this晚绑定的特性,它可以是全局对象,当前对象,或者…有人甚至因为坑大而不用this。

其实如果完全掌握了this的工作原理,自然就不会走进这些坑。来看下以下这些情况中的this分别会指向什么:

1.全局代码中的this

JavaScript

alert(this)//window

全局范围内的this将会指向全局对象,在浏览器中即使window。

2.作为单纯的函数调用

JavaScript

function fooCoder(x) {
    this.x = x;
}
fooCoder(2);
alert(x);// 全局变量x值为2

这里this指向了全局对象,即window。在严格模式中,则是undefined。

3.作为对象的方法调用

JavaScript

1 var name = "clever coder";
2 var person = {
3     name : "foocoder",
4     hello : function(sth){
5         console.log(this.name + " says " + sth);
6     }
7 }
8 person.hello("hello world");

输出 foocoder says hello world。this指向person对象,即当前对象。

4.作为构造函数

JavaScript

1 new FooCoder();

函数内部的this指向新创建的对象。

5.内部函数

JavaScript

 1 var name = "clever coder";
 2 var person = {
 3     name : "foocoder",
 4     hello : function(sth){
 5         var sayhello = function(sth) {
 6             console.log(this.name + " says " + sth);
 7         };
 8         sayhello(sth);
 9     }
10 }
11 person.hello("hello world");//clever coder says hello world

在内部函数中,this没有按预想的绑定到外层函数对象上,而是绑定到了全局对象。这里普遍被认为是JavaScript语言的设计错误,因为没有人想让内部函数中的this指向全局对象。一般的处理方式是将this作为变量保存下来,一般约定为that或者self:
JavaScript

 1 var name = "clever coder";
 2 var person = {
 3     name : "foocoder",
 4     hello : function(sth){
 5         var that = this;
 6         var sayhello = function(sth) {
 7             console.log(that.name + " says " + sth);
 8         };
 9         sayhello(sth);
10     }
11 }
12 person.hello("hello world");//foocoder says hello world

6.使用call和apply设置this
JavaScript

1 person.hello.call(person, "world");

apply和call类似,只是后面的参数是通过一个数组传入,而不是分开传入。两者的方法定义:
JavaScript

1 call( thisArg [,arg1,arg2,… ] );  // 参数列表,arg1,arg2,...
2 apply(thisArg [,argArray] );     // 参数数组,argArray

两者都是将某个函数绑定到某个具体对象上使用,自然此时的this会被显式的设置为第一个参数。

简单地总结

简单地总结以上几点,可以发现,其实只有第六点是让人疑惑的。

其实就可以总结为以下几点:

1.当函数作为对象的方法调用时,this指向该对象。

2.当函数作为淡出函数调用时,this指向全局对象(严格模式时,为undefined)

3.构造函数中的this指向新创建的对象

4.嵌套函数中的this不会继承上层函数的this,如果需要,可以用一个变量保存上层函数的this。

再总结的简单点,如果在函数中使用了this,只有在该函数直接被某对象调用时,该this才指向该对象。
JavaScript

1 obj.foocoder();
2 foocoder.call(obj, ...);
3 foocoder.apply(obj, …);

更进一步

我们可能经常会写这样的代码:
JavaScript

1 $("#some-ele").click = obj.handler;

如果在handler中用了this,this会绑定在obj上么?显然不是,赋值以后,函数是在回调中执行的,this会绑定到$(“#some-div”)元素上。这就需要理解函数的执行环境。本文不打算长篇赘述函数的执行环境,可以参考《javascript高级程序设计》中对执行环境和作用域链的相关介绍。这里要指出的时,理解js函数的执行环境,会更好地理解this。

那我们如何能解决回调函数绑定的问题?ES5中引入了一个新的方法,bind():
JavaScript

1 fun.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg
当绑定函数被调用时,该参数会作为原函数运行时的this指向.当使用new 操作符调用绑定函数时,该参数无效.
arg1, arg2, ...
当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数.

该方法创建一个新函数,称为绑定函数,绑定函数会以创建它时传入bind方法的第一个参数作为this,传入bind方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数.

显然bind方法可以很好地解决上述问题。
JavaScript

1 $("#some-ele").click(person.hello.bind(person));
2 //相应元素被点击时,输出foocoder says hello world

其实该方法也很容易模拟,我们看下Prototype.js中bind方法的源码:
JavaScript

1 Function.prototype.bind = function(){
2   var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
3   return function(){
4     return fn.apply(object,
5       args.concat(Array.prototype.slice.call(arguments)));
6   };
7 };

明白了么?

相信看完全文以后,this不再是坑~
文章来源:http://blog.jobbole.com/39305/





























































javascript箭头函数中的this详解

...用=>定义的函数:varhello=()=>console.log("Hello,Fundebug!");JavaScript箭头函数与普通函数不只是写法上的区 查看详情

第149天:javascript中this的指向详解

js中的this指向十分重要,了解js中this指向是每一个学习js的人必学的知识点,今天没事,正好总结了js中this的常见用法,喜欢的可以看看:1、全局作用域或者普通函数中this指向全局对象window。1//直接打印2console.log(this)//window34//fu... 查看详情

javascript中this详解

this是每一个想要深入学习Javascript的人必过的一关,我为this看过很多书查过很多资料,虽然对this有了一定的了解并且也经常使用this,但是如果有人问我 this是什么呀?我依旧不能给别人一个完美的解释。最近一个小的机缘,... 查看详情

详解javascript中this的工作原理

在JavaScript中this常常指向方法调用的对象,但有些时候并不是这样的,本文将详细解读在不同的情况下this的指向。一、指向window:在全局中使用this,它将会指向全局对象,因为浏览器中运行的JavaScript的全局对象默认为window,所... 查看详情

javascript的this详解

1、全局作用域下的this: 2、一般函数与严格模式下的函数的this: 3、当函数的this作为对象的方法的情况下: 4、对象原型链上的this: 对象P的原型指向o,p.a与p.a创建对象p的属性,当调用p的原型上的方法的时候,th... 查看详情

es5及es6this详解

  今天,我们学习一下JavaScript中的this。我们从什么是this,ES5及ES6中this的几种情况进行学习。让this变的soeasy,我们这里说的都是非严格模式下。this表示当前行为执行的主体,在javaScript中this不是函数独有的,但是我们主要研究... 查看详情

深入理解函数执行上下文this示例详解

...下,希望能够有所帮助,祝大家多多进步,早日升职加薪JavaScript中的this是什么关于this,我们得先从执行上下文说起。我们知道:执行上下文中包含了变量环境、词法环境、外部环境,当然也包括this,具体你可以参考下图:从... 查看详情

js中的event?event:window.event啥意思?求详解。

<scripttype="text/javascript>functionTest(event)event=event?event:window.event;<script><inputtype="button"value="clickme"onclick="Test(this)">请问:1,“onclick="Test(this)"”中的this代表什么?2,“event=event?event:window... 查看详情

jquery中的$(this)和javascript中的this

  this是JavaScript中的关键字。 $(this)可以认为是用jQuery包装过JavaScript中的this,包装后$(this)就会继承jQuery的方法。本质就是JavaScript与jQuery对象的转换$(‘a‘).click(function(){//这里的this指向当前点击的DOM节点,也就是a。可以调... 查看详情

javascript中的this作用域

javaScript中的this作用域  javaScript中的this作用域java的区别是,java中的this是在编译中确定,    javaScript中的this是在运行时确定的,不同的调用方式,决定js中的this指向不同的对象。 代码实现:  //this作用域... 查看详情

js中的this对象详解

   JS中this关键字很常见,但是它似乎变幻莫测,让人抓狂。这篇文章就来揭示其中的奥秘。    借助阮一峰老师的话:它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。这句话看似平... 查看详情

javascript中的this

JavaScript中的this指向问题在JavaScript中,this是经常使用的一个关键字,按照规定,this指向调用者,即谁调用该对象,则this指向谁,但是this存在一个缺陷,当在一个函数中定义另一个函数时,内部函数的this不会指向外部函数,而... 查看详情

javascript中call和apply的区别与详解

call和apply的详解call()方法用于操作this的函数方法是call(),它可以指定的this值和参数来执行函数。call()的第一个参数指定了函数执行时this的值,其后的所有参数都是需要被传入函数的参数。apply()方法apply()是你可以用来操作this的... 查看详情

javascript中的this陷阱的最全收集

JavaScript来自一门健全的语言,所以你可能觉得JavaScript中的this和其他面向对象的语言如java的this一样,是指存储在实例属性中的值。事实并非如此,在JavaScript中,最好把this当成哈利波特中的博格特的背包,有着深不可测的魔力... 查看详情

javascript语言中的this

JavaScript语言中的this由于其运行期绑定的特性,JavaScript中的this含义要丰富得多,它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript中函数的调用有以下几种方式:作为对象方法调用,作为函数... 查看详情

javascript中的this相关说明

1,见下面例子,注意函数中的函数中的this指的是window对象了!!!document.addEventListener(‘click‘,function(e){console.log(this);//this->document,添加在谁上的事件this就是指的谁(function(){console.log(this);//this->window})();});varo={a 查看详情

javascript中的this

下面列举一些简单的实例总结一下this的一些用法: 1.方法中的this会指向当前执行该方法的对象如:varname="window"varTom={name:"Tom";show:function(){alert(this.name)}}Tom.show();//Tom2.方法中的this不会指向声明它的对象如下varBob={name:"Bob",show:f... 查看详情

javascript中的this

在全局中执行我们看看this在全局中是什么。首先,浏览器中:console.log(this);//Window{speechSynthesis:SpeechSynthesis,caches:CacheStorage,localStorage:Storage,sessionStorage:Storage,webkitStorageInfo:DeprecatedStorageInfo…}可见,在浏览 查看详情