关于js函数中this的指向的问题

@(javascript)[JavaScript中this的指向]

关于js函数中this的指向的问题

javasript函数中this的指向一直都是许多编程入门新手的一个问题,老师把这个this的指向弄错误。下面我们可以来看看关于this指向的几种情况。

不过在讲之前,请各位始终记住一句话:
<span style="color: red;font-weight: 900;font-size: 30px;">JavaScript中的this一直指向触发这个事件(函数)的这个Objoct(对象)。</span>

第一种:函数直接添加在行内

<button onclick="alert(this.innerHTML);">this就是指向这个div盒子</button>

点击看看:
<button onclick="alert(this.innerHTML);">this就是指向这个div盒子</button>
此时的这个alert(this.innerHTML);事件是直接写在button这个元素行内的。是这个button元素触发的这个事件。

第二种:通过<span style="color: red;">对象.事件名</span>来实现

这是html代码

<button id="box">通过js事件的点击事件</button>

下面是js代码

document.getElementById("box").onclcik = function(){
    alert(this.innerHTML);
}

<button id="box">通过js事件的点击事件</button>

<script type="text/javascript">
document.getElementById("box").onclick = function(){
alert(this.innerHTML);
}
</script>

以上的两种方式都很好理解,也不做过多的说明。

第三种:函数的调用的形式

这种方式也是存在许多的变种,先来看看上面例子的一个变种。
这是html代码

<button id="box1">通过js事件的点击事件</button>

下面是js代码

document.getElementById("box1").onclick = a;
function a(){
    alert(this);
}

这一种形式的事件与上面的其实是一样的,不过是单独定义了一个函数,然后点击调用这个函数。

在看看下面的例子

<button id="box1">通过js事件的点击事件</button>

下面是js代码

document.getElementById("box1").onclick = function(){
    a();
}
function a(){
    alert(this);
}

此时的这个与上面的有很相似,不同的就是此时的这个a函数是在一个事件函数里面执行的。此时的逻辑是:我点击这个ID为box1的button,让后触发事件后面的函数function(){a();}。此时呢里面的a函数其实还没有执行。到这个函数执行的时候,执行到里面的函数了,a函数自己调用执行(函数加括号执行),那么问题来了,是谁调用的这个a函数呢?答案是:window。因为不存在上面说的两种以及Object.函数的形式。这个就有点像是定义了一个函数自执行。

像这样

function t(){
    console.log(this);
}
/**
 * 此时的这个 t 函数是由谁调用的呢(也就是鼠标哪一个对象让他执行的?)
 * 答案是的 null
 * 而在 js 中,如果 this 的指向是null会自动转换为 window
 */
t();

或者是这样:

function t(){
    function t2(){
        console.log(this);
    }
    t2()
}
t();

OK!接下来看看这个:

function intro(){
    console.log('名字是'+ this.name,this );
}
var dog = {name: "狗"};
dog.intro = intro;
dog.intro(); // 狗

分析一下:此时先定义了一个名字是intro的一个函数,在定义一个dog对象并赋值name=狗。下面的代码就是在dog这个对象上添加一个intro对象,赋值为一开始定义的那个函数intro。此时的这个dog对象就多了一个属性intro,值是函数。接着在调用这个dog.intro();。那么是谁调用的呢?很明显是这个dog对象调用的这个函数。所以此时的这个this就是指向dog对象。那this.name就是了。

OK!再来:

function intro(){
    console.log('名字是'+ this.name,this );
}
var dog = {name: "狗"};
dog.intro = intro;
dog.intro(); // 狗

var cat = {name:"猫"};
cat.intro = dog.intro;
cat.intro(); // 猫

现在多了一个cat,看这句cat.intro = dog.intro;。这个是把dog下面的intro方法赋值给了cat下面新建的一个intro方法。此时涉及到一个内存的问题。<span style="color: red;">js中的对象,函数等都是存放在内存中,给其他对象赋值为这个函数的时候就是让这个对象的这个属性指向内存中的这个函数</span>,所以,不管上面的是怎样赋值,catdogintro的值是指向同一个函数的。不同的是调用他们的对象不同,导致this不同,所以最后的this.name的值不同。

再来看看这个呢?

function intro(){
    console.log('名字是'+ this.name,this );
}
var dog = {name: "狗"};
dog.intro = intro;
dog.intro(); // 狗

var cat = {name:"猫"};
cat.intro = dog.intro;
cat.intro(); // 猫

(cat.intro = dog.intro)(); // 空 this 指向window```javascript
function intro(){
    console.log('名字是'+ this.name,this );
}
var dog = {name: "狗"};
dog.intro = intro;
dog.intro(); // 狗

var cat = {name:"猫"};
cat.intro = dog.intro;
cat.intro(); // 猫

(cat.intro = dog.intro)(); // 空 this 指向window

此时的在上面的就是多了一句(cat.intro = dog.intro)();。那为什么就指向window了呢?
上面的这个例子,涉及到的是关于计算机里面的计算,cat.intro = dog.intro 这是一个赋值运算,而赋值运算的结果是 = 右侧的值,此时这个值并不属于任何一个对象,而这个值是一个空,也可以说是一个 null ,所以此是为 null 转为指向 window。可以这么做一个比喻:

一天张三去面馆吃面,给老板说:“老板,一碗牛肉面”,做好面后,此时的这碗牛肉面这个就有了。相当于上面的intro函数,此时呢他并不属于张三。当老板把这碗面端到张三面前,这是才属于张三。OK。李四也去吃面,进入面馆,看见张三的面。对老板说:“老板,来一碗和他一样的面”。此时老板需要计算,这碗面是什么面?相当于上面的cat.intro = dog.intro计算。老板计算后才知道这碗面是牛肉面。此时让一个加括号执行,那肯定就不行了。此时的这碗面并不属于李四。赋值的结果是是什么呢?当老板把这碗面端到李四面前,这是才属于李四。这就是结果。

需要注意的点就是cat.intro = dog.intro只是一个赋值过程,值是=右边的东西。执行cat.intro = dog.intro会导致一个结果就是cat下面多了一个intro属性并且有值。

基本普通的函数中的this存在的问题就是这么多,其他的也就是上面的一些变种。

不过,可以发现,因为this指向window的存在,会导致污染全局,所以多数时候使用构造函数new的方式更可取,这样this才不会指向全局避免污染全局。

上面说了这么多。其实也就是最开始说的那句:
<span style="color: red;font-weight: 900;font-size: 30px;">JavaScript中的this一直指向触发这个事件(函数)的这个Objoct(对象)。</span>

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

推荐阅读更多精彩内容