JS中this的指向

一般涉及到这个问题,大部分的博客都说是谁调用的函数,this就指向谁,但是对于刚入门的人来说还是不太容易理解,像我当时就花了很久。。。可能是因为菜吧。
下面来讲一下我的理解
其实谁调用函数this指向谁的确是对的,但是如果基础不够好,是很容易判断错谁调用的函数
分类写比较好排版,所以分成了大概四类:

1.一般函数方法调用

//1.函数声明
var name = '张三'
function obj(){
    var a = 'obj'
    console.log(this)//window
    console.log(this.name)//张三
}
obj()//window  张三
window.obj()//window  张三

1.为什么执行了obj()输出的是window?
因为obj是全局函数,是通过window直接调用的,所以执行obj()其实等同于执行window.obj(),所以其实就是window调用的obj,所以this指向window

函数表达式其实也是一样的:

//2.函数表达式
var name = '张三'
var obj = function(){
    var a = 'obj'
    console.log(this)//window
    console.log(this.name)//张三
}
obj()//window  张三
window.obj()//window  张三

这是直接调用函数的情况,但是如果函数作为对象的属性去调用就有其他的情况了

2.作为对象的属性方法调用

//3.函数作为对象的属性去调用--例一
var  a='window';
var obj={
    name:"张三",
    age:"20",
    say:function(){
        var a='obj';
        console.log(this);//就是obj这个对象
        console.log(this.a);//undefined
        console.log(this.name);//张三
    }
}
obj.say();//obj{}  undefined  张三
window.obj.say(); //obj{}  undefined  张三

1.为什么obj.say()中的this.a是undefined呢?
因为obj.say()中的say()执行的时候是obj直接调用的,因此this指向obj,所以虽然的确是window调用的obj,但是并不是window直接调用的say(),函数的this指向的是直接调用对象,这里是obj

我们继续看

//4.函数作为对象的属性去调用--例二
var  a='window';
var obj={
    name:"张三",
    age:"20",
    say:function(){
        var a='obj';
        console.log(this);//是obj这个对象
        console.log(this.a);//undefined
        console.log(this.name);//张三
    }
    action:{
        name:"李四",
        age:"25",
        say:function(){
            var a='obj';
            console.log(this);//是action这个对象
            console.log(this.a);//undefined
            console.log(this.name);//李四
        }
    }
}
obj.say();//obj{}  undefined  张三
obj.action.say();//action{} undefined  李四
window.obj.say(); //obj{}  undefined  张三
window.obj.action.say();//action{} undefined  李四

1.为什么obj.action.say()执行结果和obj.say()不一样?
因为obj.action.say()执行say()的时候,其直接调用对象是action而不是obj,所以this指向的是action

然后我们来看另外一种情况

//5.函数作为对象的属性去调用--例三
var  a='window';
var obj={
    name:"张三",
    age:"20",
    say:function(){
        var a='obj';
        console.log(this);//就是obj这个对象
        console.log(this.a);//undefined
        console.log(this.name);//张三
        function action(){
            console.log(this);//window
            console.log(this.a);//window
            console.log(this.name);//(空)
            console.log(this.age);//undefined
        }
        action();
    }
}
obj.say();
window.obj.say(); 

1.为什么执行action()的时候this指向window?
因为action()只是在say()函数中进行了普通调用,并不是obj或者say直接调用,所以这时候指向的是全局对象window,
2.为什么this.name为空而this.age是undefined?
因为window全局对象本身就有一个默认为空的字段name,所以name是空。
3.怎么让action指向obj
在say中用一个变量保存this就然后action()中使用该变量即可。例如在say()函数中var that = this,然后action()函数中把this全部替换为that,就会达到我们想要的效果了。当然还可以使用call或者apply,有关call和apply可以看我的博客

3.作为构造函数调用

var name = 'window'
function obj(){
    this.name = 'obj'
    var age = 20
    console.log(this)//a:obj{}  b:window
    console.log(this.name)//a:obj   b:obj
    console.log(this.age)//undefined
}
var a = new obj()
var b = obj()
console.log(name)//obj

关于new可看我的博客 —— js new一个函数和直接调用函数的区别

var name = 'window'
        function obj(){
            var age = 20
            this.name = 'obj';
            console.log(this)
            console.log(this.name)
            console.log(age)
            // this.aa = function(){
            //  return this.name
            // }
        }
        var a = new obj()
        var b = obj()
        console.log(name)

1.a和b声明的时候发什么了什么?
声明a的时候使用了new,新建了一个对象a,然后obj()中的this指向a,a再链接obj的原型链,再执行obj(),所以a执行时直接调用对象是a
b其实只是window对象执行了obj()然后将返回值赋给b,如果没有返回值那么b为undefined
1.为什么b中this.name也是obj呢?
因为执行obj()的时候this指向的是window,所以在执行this.name='obj'等同于window.name='obj',所以声明b之后输出name也是obj

4.箭头函数

箭头函数中根本没有自己的this,因此this指向的是父执行上下文(简单对象(非函数)没有执行上下文)
有关于执行上下文可看 —— 执行上下文的原理及使用

5.构造函数

构造函数可以看js new
new的时候会新建一个空间并连上构造函数的原型链,再把构造函数的this指向实例,所以调用的属性和方法中的this都是指向实例

Person(){
 this.name=name
 this.age=age
 this.show=function(){
  console.log(this.name)
  console.log(this.age)
 }
}
var a = new Person('张三',20)
a.name//张三
a.age//20
a.show()//张三 20

未完待续

参考

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

推荐阅读更多精彩内容