摘要:在函數(shù)中調(diào)用時(shí)指向調(diào)用函數(shù)的對(duì)象,調(diào)用函數(shù)的在不同情況下有直接調(diào)用,此時(shí)函數(shù)內(nèi)部的指向全局對(duì)象作為對(duì)象的方法,此時(shí)指向該對(duì)象構(gòu)造函數(shù),此時(shí)指向構(gòu)造的實(shí)例對(duì)象改變指向是語言的一個(gè)關(guān)鍵字。但是有一個(gè)總的原則,那就是指的是,調(diào)用函數(shù)的那個(gè)對(duì)象。
this在全局中調(diào)用時(shí)指向的是全局對(duì)象。
this在函數(shù)中調(diào)用時(shí)指向調(diào)用函數(shù)的對(duì)象,調(diào)用函數(shù)的在不同情況下有
1.直接調(diào)用,此時(shí)函數(shù)內(nèi)部的this指向全局對(duì)象 2.作為對(duì)象的方法,此時(shí)this指向該對(duì)象 3.構(gòu)造函數(shù),此時(shí)this指向構(gòu)造的實(shí)例對(duì)象 4.call/apply改變this指向
this是Javascript語言的一個(gè)關(guān)鍵字。
它代表函數(shù)運(yùn)行時(shí),自動(dòng)生成的一個(gè)內(nèi)部對(duì)象,只能在函數(shù)內(nèi)部使用。比如,
function test(){ this.x = 1; }
隨著函數(shù)使用場(chǎng)合的不同,this的值會(huì)發(fā)生變化。但是有一個(gè)總的原則,那就是this指的是,調(diào)用函數(shù)的那個(gè)對(duì)象。
下面分四種情況,詳細(xì)討論this的用法。
這是函數(shù)的最通常用法,屬于全局性調(diào)用,因此this就代表全局對(duì)象global/window(在瀏覽器中全局對(duì)象即頂層對(duì)象指的是window,在nodejs中全局對(duì)象指的是global)。
請(qǐng)看下面這段代碼,它的運(yùn)行結(jié)果是1。
function test(){ this.x = 1; alert(this.x); alert(this === window); test(); // 1 //true
為了證明this就是全局對(duì)象,我對(duì)代碼做一些改變:
var x = 1; function test(){ alert(this.x); } test(); // 1
運(yùn)行結(jié)果還是1。再變一下:
var x = 1; function test(){ this.x = 0; } test(); alert(x); //0
當(dāng)調(diào)用函數(shù)test()后,執(zhí)行this.x 語句,而這里的this.x指向的是全局的x,所以全局的x=1在這個(gè)時(shí)候變成x=0,所以在最后alert(x)的時(shí)候數(shù)據(jù)0。
從這里可以看出函數(shù)里的 this.x 指的是全局變量x里吧。
那如果是帶有參數(shù)的函數(shù)呢?再來看看下面的例子:
var a = 20; function fun(a){ this.a = 1; console.log(a); console.log(this.a); }; fun(10); //10 //1
當(dāng)函數(shù)帶有參數(shù)時(shí),this依舊指向全局的變量,與參數(shù)沒有任何關(guān)系,上面的寫法就類似于下面的這種寫法。
var a = 20; function fun(b){ this.a = 1; console.log(b); console.log(this.a); }; fun(10); //10 //1
如果把this.a改成this.b呢?那this.b指向的是全局的變量還是函數(shù)里面的變量呢?
var a = 20; function fun(b){ this.b = 1; //沒有用var 相當(dāng)于定義了一個(gè)全局變量b,并賦值為1 console.log(b); //10 打印出傳入的參數(shù)b console.log(this.b); //1 打印出全局變量b }; fun(10); console.log(b); //1 打印出全局變量b
JavaScript里規(guī)定,全局函數(shù)里沒有用var定義的的變量是全局變量,所以這里的this.b就相當(dāng)于定義了一個(gè)全局的變量b,所以在最后能打印出變量b
現(xiàn)在你能看懂下面兩個(gè)函數(shù)了吧
var a = 20; function fun(a){ this.a = 1; console.log(a) }; console.log(a);//20 沒有執(zhí)行this.a=1 語句時(shí),全局變量a依舊為20 fun(10);//10 var a = 20; function fun(a){ this.a = 1; console.log(a) }; fun(10);//10 console.log(a);//1 執(zhí)行this.a=1 語句后,全局變量a變?yōu)?情況二:作為對(duì)象方法的調(diào)用
函數(shù)還可以作為某個(gè)對(duì)象的方法調(diào)用,這時(shí)this就指這個(gè)上級(jí)對(duì)象。
function test(){ alert(this.x); } var o = {}; o.x = 1; o.m = test; o.m(); // 1
或者用對(duì)象字面量來創(chuàng)建方法是好理解些,但都是一個(gè)意思
var pet = { words : "my dear", speak : function(){ console.log(this.words); //my dear console.log(this === pet); //true } } pet.speak();情況三 作為構(gòu)造函數(shù)調(diào)用
所謂構(gòu)造函數(shù),就是通過這個(gè)函數(shù)生成一個(gè)新對(duì)象(object)。這時(shí),this就指這個(gè)新對(duì)象。
function test(){ this.x = 1; } var o = new test(); alert(o.x); // 1
運(yùn)行結(jié)果為1。為了表明這時(shí)this不是全局對(duì)象,我對(duì)代碼做一些改變:
var x = 2; function test(){ this.x = 1; } var o = new test(); alert(x); //2
運(yùn)行結(jié)果為2,表明全局變量x的值根本沒變。
再來看一個(gè)在實(shí)際應(yīng)用中的例子
function Pet(words){ this.words = words; this.speak = function(){ console.log(this.words); console.log(this) } } var cat = new Pet("Miao"); cat.speak(); //當(dāng)nwe了一個(gè)實(shí)例對(duì)象cat后,cat擁有了自己的word屬性和speak方法,而cat.speak()調(diào)用時(shí)this指的的是cat對(duì)象自己 // Miao //Pet { words: "Miao", speak: [Function] }情況四 apply、call調(diào)用
apply()是函數(shù)對(duì)象的一個(gè)方法,它的作用是改變函數(shù)的調(diào)用對(duì)象,它的第一個(gè)參數(shù)就表示改變后的調(diào)用這個(gè)函數(shù)的對(duì)象。因此,this指的就是這第一個(gè)參數(shù)。
var x = 0;
function test(){
alert(this.x);
}
var o={};
o.x = 1;
o.m = test;
o.m.apply(); //0
apply()的參數(shù)為空時(shí),默認(rèn)調(diào)用全局對(duì)象。因此,這時(shí)的運(yùn)行結(jié)果為0,證明this指的是全局對(duì)象。
如果把最后一行代碼修改為
o.m.apply(o); //1
運(yùn)行結(jié)果就變成了1,證明了這時(shí)this代表的是對(duì)象o。
apply有兩種實(shí)際的應(yīng)用場(chǎng)景:
1.在對(duì)象中--調(diào)用時(shí)才改變this指向,如上例子,也許下面的例子好理解些
var pet = { words : "my dear", speak : function(say){ console.log(say + " " +this.words) } } pet.speak("hello");//hello my dear //利用apple調(diào)用時(shí)改變this的指向 var dog = { words :"wang" } pet.speak.call(dog,"hello");//hello wang pet.speak("hello")//hello my dear
2.實(shí)現(xiàn)繼承時(shí)的構(gòu)造函數(shù)--定義時(shí)改變this指向
function Pets(words,sex){ this.words = words; this.sex = sex; this.speak = function(){ console.log(this.words + " " + this.sex) } } function Dog(words,sex){ //Pets.call(this, words, sex); //Pets.apply(this,[words, sex]) Pets.apply(this,arguments) } var dog = new Dog("wang","girl") dog.speak();//wang,girl
參考資料:
1.《JavaScript的this用法》--阮一峰
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/90135.html
摘要:面向?qū)ο竺嫦驅(qū)ο缶幊痰娜Q是,簡(jiǎn)稱,面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實(shí)世界模型的一種編程模式。面向?qū)ο缶幊痰娜齻€(gè)主要特征是封裝繼承多態(tài)。 面向?qū)ο?面向?qū)ο缶幊痰娜Q是Object Oriented Programming,簡(jiǎn)稱OOP,面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實(shí)世界模型的一種編程模式。面向?qū)ο缶幊炭梢钥醋鍪鞘褂靡幌盗袑?duì)象相互協(xié)作的軟件設(shè)計(jì),面向?qū)ο蟪绦蛟O(shè)計(jì)的目的是在編程中促...
摘要:組合方式實(shí)現(xiàn)繼承原型鏈構(gòu)造函數(shù)喵喵喵汪汪汪與的唯一區(qū)別是多了這一句組合方式實(shí)現(xiàn)了對(duì)構(gòu)造函數(shù)內(nèi)和原型上所有屬性和方法的繼承,并且的實(shí)例對(duì)象之間也不會(huì)相互干擾。 前言 關(guān)于JavaScript繼承相關(guān)的定義和方法網(wǎng)上已經(jīng)有很多解釋啦,本菜鳥就不抄抄寫寫惹人嫌了,本文主要探討三種基本的繼承方式并且給出優(yōu)化方案。 正文 借助構(gòu)造函數(shù)實(shí)現(xiàn)繼承 function Parent1() { ...
摘要:綁定使用方式進(jìn)行調(diào)用函數(shù)時(shí),會(huì)發(fā)生構(gòu)造函數(shù)的調(diào)用。先上圖,然后根據(jù)文字閱讀使用調(diào)用函數(shù)之后,該函數(shù)才作為構(gòu)造函數(shù)進(jìn)行調(diào)用,構(gòu)造一個(gè)全新的對(duì)象賦值給,而對(duì)象的指向了的對(duì)象,的對(duì)象有一個(gè)屬性指向的構(gòu)造函數(shù)這個(gè)就是的原型鏈,也是的特性。 javascript語言是在運(yùn)行時(shí)前即進(jìn)行編譯的,而this的綁定也是在運(yùn)行時(shí)進(jìn)行綁定的。也就是說,this實(shí)際上是在函數(shù)被調(diào)用時(shí)候發(fā)生綁定的,它指向什么完...
摘要:在這其中我們就逃不開要討論繼承原型對(duì)象構(gòu)造函數(shù)實(shí)例了。想要獲得某一類型的構(gòu)造函數(shù)可以用來獲得,也可以對(duì)該屬性進(jìn)行賦值操作。三上面就提到一點(diǎn)是指構(gòu)造函數(shù)的原型對(duì)象,它是一個(gè)對(duì)象,它是構(gòu)造函數(shù)的屬性。 原型鏈這一個(gè)話題,需要和很多概念一起講,才能串成一個(gè)比較系統(tǒng)的知識(shí)點(diǎn)。在這其中我們就逃不開要討論繼承、原型對(duì)象、構(gòu)造函數(shù)、實(shí)例了。 一、構(gòu)造函數(shù) 構(gòu)造函數(shù)是一類特殊的函數(shù),它的作用是用來生成...
摘要:工廠模式優(yōu)點(diǎn)集中實(shí)例化,可以傳參等缺點(diǎn)分不清屬于哪個(gè)對(duì)象我們先來談?wù)剝?yōu)點(diǎn),看例子集中實(shí)例化返回實(shí)例化對(duì)象返回返回不難看出,工廠模式比上面的例子減少了很多代碼。 ECMAscript開發(fā)的兩種模式:1.過程化 2.OOP(面向?qū)ο? 面向?qū)ο蟮恼Z言有一個(gè)標(biāo)志,那就是類的概念,而通過類可以創(chuàng)建任意多個(gè)具有相同屬性的方法的對(duì)象。但是ECMAscript中沒有類的概念! 又談作用域 首先...
摘要:構(gòu)造函數(shù)上一章我們講了工廠模式,它的缺點(diǎn)就是無法識(shí)別到底哪個(gè)屬于哪個(gè)的問題。我們可以用構(gòu)造函數(shù)來解決這個(gè)識(shí)別問題。來比較構(gòu)造函數(shù)內(nèi)的值就可以看出到底是什么類型。 構(gòu)造函數(shù) 上一章我們講了工廠模式,它的缺點(diǎn)就是無法識(shí)別到底哪個(gè)屬于哪個(gè)的問題。我們可以用構(gòu)造函數(shù)來解決這個(gè)識(shí)別問題。 //構(gòu)造函數(shù) function Create(a,b) { this.a =a; this...
閱讀 1780·2021-11-18 10:02
閱讀 2292·2021-11-15 11:38
閱讀 2752·2019-08-30 15:52
閱讀 2339·2019-08-29 14:04
閱讀 3306·2019-08-29 12:29
閱讀 2157·2019-08-26 11:44
閱讀 1083·2019-08-26 10:28
閱讀 921·2019-08-23 18:37