Javascript 中 this 的指向

   大家好,我是IT修真院武汉第10期学员,一枚正直、纯洁、善良的前端程序员。

   今天给大家分享一下,修真院官网任务js-2,深度思考的知识点——函数表达式跟函数声明的区别;

1.背景介绍

JAVASCRIPT中THIS指的是什么?

this是JavaScript语言中定义的众多关键字之一,它的特殊在于它自动定义于每一个函数域内,在函数运行时,this会自动生成一个内部对象,这个对象只能在函数内部使用。同时,随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象。

那什么THIS的指向又是什么呢?

在JavaScript中,this是动态绑定的,它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。这就导致了this具备了多重含义,可以使得JavaScript更灵活的使用。但是,带来了灵活性的同时也会给我们初学者带来不少困惑。

2.知识剖析  

var name = '小明';

function look() {     

        var name = '二明';   

        console.log(this.name);    

        console.log(this); 

}; 

look(); //小明

总结:在全局作用域中它的 this 执行当前的全局对象(浏览器端是 Window),所以才会在全局环境下查找'name',然后打印出来

var name = '小明';

var name2 = {     

        name: '二明',     

        age: 20,   

         look: function(){       

        console.log(this.name);         

        console.log(this.age);     

        } 

name2.look();

这里的打印的结果是打印的第一个是二明,第二个是20。因为调用look函数的是name2这个对象,所以this指向的是name2中的name属性的指向只在函数中定义的话是确定不了的,只有当被函数执行的时候才能确定this到底指向谁,也就是谁调用了这个函数。

var name ='小明';

var name2 = {

        name:'二明',

        func:{

                name:'三明',

                look:function(){

                    console.log(this.name);

                }

        }

}

name2.func.look();

这里的话,第一个是函数被name2调用的,本应打印的是二明,但是最后的打印结果却是三明,是为什么呢。我们可以看下下面的图

调用之间的关系

THIS的指向的三种情况

1.如果一个函数有this,但是它没有被上一级对象所调用,那么它指向的就是window。在严格模式下指向的是undefined。

2.如果一个函数中有this,这个函数有被上一级所调用,那么它指向的就是调用它的对象。

3.如果一个函数中有this,且这个函数外层被多个对象包含,尽管最终这个函数是被最外层的对象所调用,this指向的也只是函数上一级的对象。

var name ='小明';

var name2 = {

        name:'二明',

        func:{

                look:function(){

                        console.log(this.name);

                }

        }

}

name2.func.look();//undefined

虽然函数look()最终是被func调用,哪怕func中没有name这个属性,this指向的依然是func,所以打印的结果为undefined。但是还有一种特殊情况:

var name ='小明';

var name2 = {

        name:'二明',

        func:{

                name:'三明',

                look:function(){

                        console.log(this.name);

                }

        }

}

var a = name2.func.look;

a();

这里的话this最终打印的是小明,却不是我们想象中的三明,这是因为我们重新声明变量a,并把look函数赋值给它,最后执行函数a()的时候,调用a()是Window对象。那句话:谁调用this,this就指向谁.

3、常见问题

现象:下面的代码两次打印的this不一样

var obj = {     

        name: 'qiutc',     

        foo: function() {         

                console.log(this);     

        },     

        foo2: function() {        

                console.log(this);         

                setTimeout(this.foo, 1000);     

        } 

obj.foo2();

4、解决方案

我们可以这么解决:利用 闭包 的特性来处理

var obj = {

        name:'qiutc',

        foo: function() {

                console.log(this);

        },

        foo2: function() {

                console.log(this);

                var _this= this;

                setTimeout(function() {

                        console.log(this);// Window

                        console.log(_this);// Object {name: "qiutc"}

                },1000);

        }

}

obj.foo2();

可以看到直接用 this 仍然是 Window;因为 foo2 中的 this 是指向 obj,我们可以先用一个变量 _this 来储存,然后在回调函数中使用 _this,就可以指向当前的这个对象了

执行这段代码我们会发现两次打印出来的 this 是不一样的:

第一次是 foo2 中直接打印 this,这里指向 obj 这个对象,我们毋庸置疑;

但是在 setTimeout 中执行的 this.foo ,却指向了全局对象,这里不是把它当作函数的方法使用吗?这一点经常让很多初学者疑惑;

其实,setTimeout 也只是一个函数而已,函数必然有可能需要参数,我们把 this.foo 当作一个参数传给 setTimeout 这个函数,就像它需要一个 fun 参数,在传入参数的时候,其实做了个这样的        操作 fun = this.foo,看到没有,这里我们直接把 fun 指向 this.foo 的引用;执行的时候其实是执行了 fun() 所以已经和 obj 无关了,它是被当作普通函数直接调用的,因此 this 指向全局对象。

这个问题是很多异步回调函数中普遍会碰到的

6.扩展思考

问题:当this遇到return时会发生什么?

答:如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例

问题:当this在一个对象里面的对像里,这是this指向哪?

答:谁调用this,this就指向谁;这时候指向的是这个对象;

问题:this看起来很简单,有什么需要注意的么?

答:讲起来肯定简单,用起来却很复杂。

7.参考文献

参考一:彻底理解JS中this的指向

参考二:阮一峰的博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352