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