【成都第一百零七期】JS中this的指向

JS中this的指向

【成都小课堂】

1.背景介绍

2.知识剖析

3.常见问题

4.解决方案

5.编码实战

6.扩展思考

7.参考文献

8.更多讨论

1.背景介绍

this是Javascript语言的一个关键字。它代表函数运行时,自动生成的一个内部对象。

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

2.知识剖析

全局环境中的this

function test() {

console.log(this);

}

test();

总结:在全局作用域中它的this执行当前的全局对象(浏览器端是Window,node中是global)

严格模式‘use strict’下的this

'use strict';

function test() {

console.log(this);

};

test();

// undefined

原因:this并不会指向全局,而是undefined,这样的做法是为了消除js中一些不严谨的行为。

在javascritp中,不一定只有对象方法的上下文中才有this, 全局函数调用和其他的几种不同的上下文中也有this指代。 它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript中函数的调用有以下几种方式:作为对象方法调用,作为函数调用,作为构造函数调用,和使用apply或call调用。

1.作为对象方法调用:this被自然绑定到该对象,也就是说this就指这个上级对象

var point = {

x : 0,

y : 0,

moveTo : function(x, y) {

this.x = this.x + x;

this.y = this.y + y;

}

};

point.moveTo(1, 1)//this绑定到当前对象,即point对象

2.作为函数调用:this被绑定到全局对象

function makeNoSense(x) {

this.x = x;

}

makeNoSense(5);

x;// x已经成为一个值为5的全局变量

3.作为构造函数调用:this绑定到新创建的对象上,也就是说this就指这个新对象

function Point(x, y){

this.x = x;

this.y = y;

}

注:构造函数不使用new调用,则和普通函数一样。一般地,构造函数首字母大写

4.使用apply或call调用:在JavaScript中函数也是对象,对象则有方法,apply和call就是函数对象的方法。

function Point(x, y){

this.x = x;

this.y = y;

this.moveTo = function(x, y){

this.x = x;

this.y = y;

}

}

var p1 = new Point(0, 0);

var p2 = {x: 0, y: 0};

p1.moveTo(1, 1);

p1.moveTo.apply(p2, [10, 10]);

3、常见问题

问题一

var obj = {

name: 'qiutc',

foo: function() {

console.log(this);

},

foo2: function() {

console.log(this);

setTimeout(this.foo, 1000);

}

}

obj.foo2();

现象:两次打印的this不一样

问题二

'use strict';

function foo() {

console.log(this);

}

setTimeout(foo, 1);

// window

现象:加了严格模式,foo调用也没有指定this,应该是出来undefined,但是这里仍然出现了全局对象

4、解决方案

问题一起因是因为 setTimeout() 将 this.foo 作为了自身的参数,这时候 this.foo 是作为一个fun参数去获取全局的变量了。

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

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,就可以指向当前的这个对象了

问题二

setTimeout方法在调用传入函数的时候,如果这个函数没有指定了的this,那么它会做一个隐式的操作—-自动地注入全局上下文,等同于调用foo.apply(window)而非foo();

5、编码实战

对于内部函数,即声明在另外一个函数体内的函数,这种绑定到全局对象的方式会产生另外一个问题。我们仍然以前面提到的point对象为例,这次我们希望在moveTo方法内定义两个函数,分别将x,y坐标进行平移。结果可能出乎大家意料,不仅point对象没有移动,反而多出两个全局变量x,y

var point = {

x : 0,

y : 0,

moveTo : function(x, y) {

//内部函数

var moveX = function(x) {

this.x = x;//this绑定到了哪里?

};

//内部函数

var moveY = function(y) {

this.y = y;//this绑定到了哪里?

};

moveX(x);

moveY(y);

}

};

point.moveTo(1, 1);

point.x; //==>0

point.y; //==>0

x; //==>1

y; //==>1

这属于JavaScript的设计缺陷,正确的设计方式是内部函数的this应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,聪明的JavaScript程序员想出了变量替代的方法,约定俗成,该变量一般被命名为that。

var point = {

x : 0,

y : 0,

moveTo : function(x, y) {

var that = this;

//内部函数

var moveX = function(x) {

that.x = x;

};

//内部函数

var moveY = function(y) {

that.y = y;

}

moveX(x);

moveY(y);

}

};

point.moveTo(1, 1);

point.x; //==>1

point.y; //==>1

6.扩展思考

问题:如何理解this?

当一个函数被调用时,拥有它的object会作为this传入。在全局下,就是window or global,其他时候就是相应的object。 也可以看到,call和apply就是利用这一点实现更改this值的

7.参考文献

参考一:深入浅出JavaScript中的this

参考二:JavaScript中的this !

参考三:JavaScript中的this用法与指向

参考四:如何理解JavaScript中的this关键字?

8、更多讨论

this含义为何如此丰富?

理解this的指向有何意义?

答案链接


小课堂视频:


_2017-0512-1904-26_腾讯视频


PPT链接


------------------------------------------------------------------------------------------------------------------------

技能树.IT修真院

“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。

这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。快来与我一起学习吧 !

http://www.jnshu.com/login/1/96029204

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

推荐阅读更多精彩内容