javaScript的this指向总结(原创)

    在javascript中this的指向一直是前端同事的心头病,也同时是各面试题的首选,现在我们就来总结一下js中this的指向。首先需要了解一下几个概念:

1:全局变量默认挂载在window对象下
2:一般情况下this指向它的调用者
3:es6的箭头函数中,this指向创建者,并非调用者
4:通过call、apply、bind可以改改变this的指向

下面我们具体分析一下

1:在函数调用时

  (非严格模式)

1     const func = function () {
2         console.log(this);
3         const func2 = function () {
4             console.log(this);
5         };
6         func2(); //Window
7     };
8     func();  //Window

  (严格模式)

1     ‘use strict‘
2     const func = function () {
3         console.log(this);
4         const func2 = function () {
5             console.log(this);
6         };
7         func2(); //undefined
8     };
9     func();  //undefined 

    结合第四和第一两条规则:func这个函数是全局的,默认挂载在window对象下,this指向它的调用者即window,所以输出window对象,但是在严格模式下,this不允许指向全局变量window,所以输出为undefined(func2在函数直接调用时默认指向了全局window,其实这属于javascript设计上的缺陷,正确的设计方式是内部函数的this 应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,聪明的 JavaScript 程序员想出了变量替代的方法,约定俗成,该变量一般被命名为 that。这种方式在接下来会讲到)。

2:作为对象方法

 1     const user = {
 2
 3         userName: ‘小张‘,
 4         age: 18,
 5         selfIntroduction: function () {
 6             const str = ‘我的名字是:‘ + this.userName + ",年龄是:" + this.age;
 7             console.log(str);
 8
 9             const loop = function () {
10                 console.log(‘我的名字是:‘ + this.userName + ",年龄是:" + this.age);
11             };
12
13             loop();     //我的名字是:undefined,年龄是:undefined
14
15         }
16     };
17
18     user.selfIntroduction();    //我的名字是:小张,年龄是:18

    按照咱的第一条规则,this指向他的调用者,selfIntroduction()方法的调用者是user,所以在selfIntroduction()方法内部this指向了他的父对象即user,而loop方法输出的为undefined的原因就是我在上面所说的javascript的设计缺陷了,在这种情况下,我们通常选择在selfIntroduction()方法里将this缓存下来。

 1     const user = {
 2         userName: ‘小张‘,
 3         age: 18,
 4         selfIntroduction: function () {
 5             const str = ‘我的名字是:‘ + this.userName + ",年龄是:" + this.age;
 6             console.log(str);
 7
 8             const that=this;
 9
10             const loop = function () {
11                 console.log(‘我的名字是:‘ + that.userName + ",年龄是:" + that.age);
12             };
13
14             loop();     //我的名字是:小张,年龄是:18
15
16         }
17     };
18
19     user.selfIntroduction();    //我的名字是:小张,年龄是:18

此时loop的this指向就理想了。

 1     const user={
 2
 3         userName:‘小张‘,
 4         age:18,
 5         selfIntroduction:function(){
 6             const str=‘我的名字是:‘+this.userName+",年龄是:"+this.age;
 7             console.log(str);
 8         }
 9     };
10
11     const other =user.selfIntroduction;
12     other();  //我的名字是:undefined,年龄是:undefined
13
14     const data={
15         userName:‘小李‘,
16         age:19,
17     };
18     data.selfIntroduction=user.selfIntroduction;
19     data.selfIntroduction();  //我的名字是:小李,年龄是:19

  在看这段代码,将selfIntroduction()赋值给了全局变量other,调用other()方法,other挂载在全局函数window对象下,window对象下没有userName 和 age 这两个属性,所以输出为undefined。第二段代码,申明了data对象,包含了username和age属性,记住我们的第二条规则一般情况下this指向它的调用者,大家就明白了,data是selfIntroduction()的函数的调用者,所以输出了data的userName和age。

3:在html里作为事件触发

<body>

    <div id="btn">点击我</div>

</body>
1         const btn=document.getElementById(‘btn‘);
2
3         btn.addEventListener(‘click‘,function () {
4             console.log(this);  //<div id="btn">点击我</div>
5         })

在种情况其实也是遵循了第二条规则一般情况下this指向它的调用者,this指向了事件的事件源即event。

4:new关键字(构造函数)

1     const  fun=function(userName){
2         this.userName=userName;
3     }
4
5     const  user=new fun(‘郭德纲‘);
6
7     console.log(user.userName);  //郭德纲

这个就不多赘述了,new关键字构造了一个对象实例,赋值给了user,所以userName就成为了user对象的属性。

5:es6(箭头函数)

1     const func1=()=>{
2
3         console.log(this);
4
5     };
6
7     func1(); //Window 
 1     const data={
 2         userName:‘校长‘,
 3         selfIntroduction:function(){
 4             console.log(this); //Object {userName: "校长", selfIntroduction: function}
 5
 6             const func2=()=>{
 7                 console.log(this);  //Object {userName: "校长", selfIntroduction: function}
 8             }
 9
10             func2();
11         }
12
13     }
14
15     data.selfIntroduction();

  大家在看看我开头说的第三条准则:es6的箭头函数中,this指向创建者,并非调用者,fun1 在全局函数下创建,所以this指向全局window,而fun2在对象data下创建,this指向data对象,所以在func2函数内部this指向data对象,个人认为es6的箭头函数的this指向是对我上面所说的javascript设计缺陷的改进,(个人认知)。

6:改变this的指向

  call、apply、bind这三个函数是可以人为的改变函数的this指向的,在这里就不多说这三者的区别了,在往后的博客里我会详细解释这三者的区别的。现在先拿一个来举一个例子

1 const func=function(){
2     console.log(this);
3 };
4
5 func(); //window
6
7 func.apply({userName:"郭德纲"});  //Object {userName: "郭德纲"}

  这三个方法都是可以人为的改变this的指向,区别是call、apply会将该方法绑定this之后立即执行,而bind方法会返回一个可执行的函数。

说这很多总结起来就是我开头说的4点

1:全局变量默认挂载在window对象下
2:一般情况下this指向它的调用者
3:es6的箭头函数中,this指向创建者,并非调用者
4:通过call、apply、bind可以改改变this的指向

说实话第一次写博客,确实挺忐忑的,会不会有人看我的博客?会不会写的不正确?……想好多了,总结了:不好的地方欢迎指正。

  

       

   

时间: 2024-12-19 04:29:09

javaScript的this指向总结(原创)的相关文章

JavaScript this的指向

this 的指向有几种情况: 全局对象(指向 window): 作为普通函数调用(指向 window): 作为对象方法调用(一般指向该对象): 构造器调用(一般指向构造器函数): Function.prototype.call 或 Function.prototype.apply 调用(指向 Function). 1. 全局对象的this 1 console.log(this); // this指向于window 2 3 function test(){ 4 console.log(11); 5

javascript this指针指向?

前言 理解javascript的指针就需要先了解js的执行环境和作用域!执行环境的定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象,环境中定义的所有的变量和函数都保存在这个对象中.虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它. 1.全局执行环境 全局执行环境是最外围的一个执行环境,根据js实现的宿主环境的不同,表示执行环境的对象也不一样.在web浏览器中认为window就是全局执行的对象.因此所有的全局变量和函数都是作为w

JavaScript中this指向

一.重点来了,this指向问题: 1.this指向之普通函数. 2.this指向之对象 3.this指向之构造函数 4.this指向之(call,apply)动态更改this指向. 二.具体分析如下 1.普通函数 // 第23行的调用者为null,this指向也为null,// 所以这时js把this指向了window对象,所以弹出的结果是// n,这样不好的是会污染全局函数内带this的操作,不能直接调用; 2.对象 // 第34行是对象的say方法指针指向了一个存在的函数say();// 所

十分钟彻底理解javascript 的 this指向,不懂请砸店

函数的this指向谁,和函数在哪里被定义的,函数在哪里被执行的没有半毛钱关系,只遵守下面的规律: 在非严格模式中: 1.自执行函数里面,this永远指向window; <script> var a = 1; var o = { a: 2, fn: (function(){ //自执行函数,在定义的时候就已经执行啦 console.log('自执行函数里面是window',this.a); //自执行函数里面的this指向的是window return function() { // 但是这里的

JavaScript this的指向问题

this的指向 在函数创建的时候,this的指向还未确定,它最终指向调用它的对象 window.onload=function(){ window.a="我的曾经" function da(){ console.log(this.a) } da() //我的曾经} 解:window对da()函数进行调用,故this指向window window.onload=function(){ window.a="我的曾经" var bn={ a:"小白",

JavaScript中this指向的简单理解

首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然网上大部分的文章都是这样说的,虽然在很多情况下那样去理解不会出什么问题,但是实际上那样理解是不准确的,所以在你理解this的时候会有种琢磨不透的感觉),那么接下来我会深入的探讨这个问题. 为什么要学习this?如果你学过函数式编程,面向对象编程,那你肯定知道干什么用的,如果你没有学过,那么暂时可以不

JavaScript关键字this指向

在js中this始终指向一个调用函数的那个对象 var a='有种你干掉我啊'; //纯粹调用函数 function test(){ console.log(this.a);//默认指向全局对象 } //test();//=>windows.test() //作为对象的方法被调用 Function.prototype.log=function(){ console.log(this.a); } //此时t为一个函数对象,注意js中一切皆为对象,函数是特殊的对象,具有prototype而已 //t

javascript“命名空间”的费曼输出[原创]

Javascript由于没有命名空间的概念,所以好多的框架或库就用了某些“命名空间”的技巧.在学习作为函数的命名空间时,我翻阅了好多的书本和blog,很多的概念和说明都是要么过于烦杂或过于简单.现在由我来进行一个的系统的描述和介绍. 一.浏览器启动后的初步理解 1.我们要上网,就要打开浏览器,输入网址,浏览器就负责渲染和相应用户的鼠标动作.而打开浏览器这个进程后,浏览器的网络线程负责解析网址为ip地址,去网页服务器下载网页文件到本地硬盘,我就称这个线程是network线程:另外一个线程是负责解析

JavaScript中this指向问题(函数的调用方式)

在ES6之前,函数内部的this是由函数的调用方式决定的 函数调用 var age = 18; var p ={ age : 15, say : function(){ console.log(this.age) } } var f1 = p.say; f1(); 这时是函数调用(是由window调用,即f1() = window.f1()). 此时结果为18,因为this指向window. 方法调用 var age = 18; var p ={ age : 15, say : function