国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Javascript this 的一些學(xué)習(xí)總結(jié)01【轉(zhuǎn)自cnblogs的JKhuang】

Thanatos / 1275人閱讀

摘要:函數(shù)上下文中的值是函數(shù)調(diào)用者提供并且由當(dāng)前調(diào)用表達(dá)式的形式而定的。然而,由于對于來說沒有任何意義,因此會(huì)隱式轉(zhuǎn)換為全局對象。這里注意到四個(gè)表達(dá)式中,只有第一個(gè)表達(dá)式是指向?qū)ο蟮模渌齻€(gè)表達(dá)式則執(zhí)行。

摘要

相信有C++、C#或Java等編程經(jīng)驗(yàn)的各位,對于this關(guān)鍵字再熟悉不過了。由于Javascript是一種面向?qū)ο蟮木幊陶Z言,它和C++、C#或Java一樣都包含this關(guān)鍵字,接下來我們將向大家介紹Javascript中的this關(guān)鍵字。

正文

由于許多面向?qū)ο蟮木幊陶Z言都包含this關(guān)鍵字,我們會(huì)很自然地把this和面向?qū)ο蟮木幊谭绞铰?lián)系在一起,this通常指向利用構(gòu)造器新創(chuàng)建出來的對象。而在ECMAScript中,this不僅僅只用來表示創(chuàng)建出來的對象,也是執(zhí)行上下文的一個(gè)屬性:

activeExecutionContext = {
  // Variable object.
  VO: {...},
  this: thisValue
};

全局代碼中的this

// Global scope
// The implicit property of 
// the global object
foo1 = "abc";
alert(foo1); // abc
 
// The explicit property of 
// the global object
this.foo2 = "def";
alert(foo2); // def

// The implicit property of 
// the global object
var foo3 = "ijk";
alert(foo3); // ijk

前面我們通過顯式和隱式定義了全局屬性foo1、foo2和foo3,由于this在全局上下文中,所以它的值是全局對象本身(在瀏覽器中是window object);接下來我們將介紹函數(shù)中的this。

函數(shù)中的this

當(dāng)this在函數(shù)代碼中,情況就復(fù)雜多了,并且會(huì)引發(fā)很多的問題。

函數(shù)代碼中this值的第一個(gè)特性(同時(shí)也是最主要的特性)就是:它并非靜態(tài)的綁定在函數(shù)上。

正如此前提到的,this的值是在進(jìn)入執(zhí)行上下文(Excution context)的階段確定的,并且在函數(shù)代碼中的話,其值每次都不盡相同。

然而,一旦進(jìn)入執(zhí)行代碼階段,其值就不能改變了。如果要想給this賦一個(gè)新的值是不可能的,因?yàn)樵谀菚r(shí)this根本就不是變量了。

接下來,我們通過具體的例子說明函數(shù)中的this。

首先我們定義兩個(gè)對象foo和person,foo包含一個(gè)屬性name,而person包含屬性name和方法say(),具體的定義如下:

// Defines foo object.
var foo = {
    name: "Foo"
};

// Defines person object.
var person = {
    name: "JK_Rush",
    say: function() {
        alert(this === person);
        alert("My name is " + this.name);
    }
};

person.say();  // My name is JK_Rush

// foo and person object refer to 
// the same function say
foo.say = person.say;

foo.say();    // My name is Foo.

通過上面的代碼,我們發(fā)現(xiàn)調(diào)用person的say()方法時(shí),this指向person對象,當(dāng)通過賦值方式使得foo的say()方法指向peson中的say()方法時(shí)。我們調(diào)用foo的say()方法,發(fā)現(xiàn)this不是指向person對象,而不是指向foo對象,這究竟是什么原因呢?

首先,我們必須知道this的值在函數(shù)中是非靜態(tài)的,它的值確定在函數(shù)調(diào)用時(shí),具體代碼執(zhí)行前,this的值是由激活上下文代碼的調(diào)用者決定的,比如說,調(diào)用函數(shù)的外層上下文;更重要的是,this的值是由調(diào)用表達(dá)式的形式?jīng)Q定的,所以說this并非靜態(tài)的綁定在函數(shù)上

由于this并非靜態(tài)地綁定在函數(shù)上,那么我們是否可以在函數(shù)中動(dòng)態(tài)地修改this的值呢?

// Defines foo object.
var foo = {
    name: "Foo"
};

// Defines person object.
var person = {
    name: "JK_Rush",
    say: function() {
        alert(this === person);
        this = foo;  // ReferenceError
        alert("My name is " + this.name);
    }
};

person.say();  // My name is JK_Rush

現(xiàn)在我們在方法say()中,動(dòng)態(tài)地修改this的值,當(dāng)我們重新執(zhí)行以上代碼,發(fā)現(xiàn)this的值引用錯(cuò)誤。這是由于一旦進(jìn)入執(zhí)行代碼階段(函數(shù)調(diào)用時(shí),具體代碼執(zhí)行前),this的值就確定了,所以不能改變了。

引用類型

前面我們提到this的值是由激活上下文代碼的調(diào)用者決定的,更重要的是,this的值是由調(diào)用表達(dá)式的形式?jīng)Q定的;那么表達(dá)式的形式是如何影響this的值呢?

首先,讓我們介紹一個(gè)內(nèi)部類型——引用類型,它的值可以用偽代碼表示為一個(gè)擁有兩個(gè)屬性的對象分別是:base屬性(屬性所屬的對象)以及該base對象中的propertyName屬性:

// Reference type.
var valueOfReferenceType = {
  base: mybase,
  propertyName : "mybasepropertyName" 
};

引用類型的值只有可能是以下兩種情況:

當(dāng)處理一個(gè)標(biāo)識符的時(shí)候

或者進(jìn)行屬性訪問的時(shí)候

標(biāo)識符其實(shí)就是變量名、函數(shù)名、函數(shù)參數(shù)名以及全局對象的未受限的屬性

// Declares varible.
var foo = 23;

// Declares a function
function say() {
    // Your code.
}

中間過程中,對應(yīng)的引用類型如下:

// Reference type.
var fooReference = {
  base: global,
  propertyName: "foo"
};
 
var sayReference = {
  base: global,
  propertyName: "say"
};

我們知道Javascript中屬性訪問有兩種方式:點(diǎn)符號和中括號符號:

// Invokes the say method.
foo.say();
foo["say"]();

由于say()方法是標(biāo)識符,所以它對應(yīng)于foo對象引用類型如下:

// Reference type.
var fooSayReference = {
  base: foo,
  propertyName: "say"
};

我們發(fā)現(xiàn)say()方法的base屬性值為foo對象,那么它對應(yīng)的this屬性也將指向foo對象。

假設(shè),我們直接調(diào)用say()方法,它對應(yīng)的引用類型如下:

// Reference type.
var sayReference = {
  base: global,
  propertyName: "say"
};

由于say()方法的base屬性值為global(通常來說是window object),那么它對應(yīng)的this屬性也將指向global。

函數(shù)上下文中this的值是函數(shù)調(diào)用者提供并且由當(dāng)前調(diào)用表達(dá)式的形式而定的。如果在調(diào)用括號()的左邊有引用類型的值,那么this的值就會(huì)設(shè)置為該引用類型值的base對象。 所有其他情況下(非引用類型),this的值總是null。然而,由于null對于this來說沒有任何意義,因此會(huì)隱式轉(zhuǎn)換為全局對象。

函數(shù)調(diào)用以及非引用類型

前面我們提到,當(dāng)調(diào)用括號左側(cè)為非引用類型的時(shí),this的值會(huì)設(shè)置為null,并最終隱式轉(zhuǎn)換為全局對象。

現(xiàn)在我們定義了一個(gè)匿名自執(zhí)行函數(shù),具體實(shí)現(xiàn)如下:

// Declares anonymous function
(function () {
  alert(this); // null => global
})();

由于括號()左邊的匿名函數(shù)是非引用類型對象(它既不是標(biāo)識符也不屬于屬性訪問),因此,this的值設(shè)置為全局對象。

// Declares object.
var foo = {
  bar: function () {
    alert(this);
  }
};
 
(foo.bar)();          // foo.
(foo.bar = foo.bar)(); // global?
(false || foo.bar)();  // global?
(foo.bar, foo.bar)();  // global

這里注意到四個(gè)表達(dá)式中,只有第一個(gè)表達(dá)式this是指向foo對象的,而其他三個(gè)表達(dá)式則執(zhí)行g(shù)lobal。

現(xiàn)在我們又有疑問了:為什么屬性訪問,但是最終this的值不是引用類型對象而是全局對象呢?

我們注意到表達(dá)式二是賦值(assignment operator),與表達(dá)式一組操作符不同的是,它會(huì)觸發(fā)調(diào)用GetValue方法(參見11.13.1中的第三步)。 最后返回的時(shí)候就是一個(gè)函數(shù)對象了(而不是引用類型的值了),這就意味著this的值會(huì)設(shè)置為null,最終會(huì)變成全局對象。

第三和第四種情況也是類似的——逗號操作符和OR邏輯表達(dá)式都會(huì)觸發(fā)調(diào)用GetValue方法,于是相應(yīng)地就會(huì)丟失原先的引用類型值,變成了函數(shù)類型,this的值就變成了全局對象了。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/88096.html

相關(guān)文章

  • Javascript Context和Scope學(xué)習(xí)總結(jié)02【轉(zhuǎn)自cnblogsJKhuang

    摘要:總結(jié)本博文通過介紹執(zhí)行上下文和作用域的異同的使用以及變量對象,讓我們加深對語言特性的理解。首先,我們介紹了執(zhí)行上下文和的的關(guān)系,并且執(zhí)行上下文是具有對象的然后,介紹了作用域使變量在作用域范圍內(nèi)可見,并且作用域是基于函數(shù)的。 接上一篇Javascript Context和Scope的學(xué)習(xí)總結(jié)01【轉(zhuǎn)自cnblogs的JKhuang】(可能是segmentfault對單篇文章發(fā)布字?jǐn)?shù)有限制...

    Aldous 評論0 收藏0
  • Javascript Context和Scope學(xué)習(xí)總結(jié)01轉(zhuǎn)自cnblogsJKhuang

    摘要:正文執(zhí)行環(huán)境也稱為環(huán)境是中最為重要的一個(gè)概念。執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了它們各自的行為。簡而言之,執(zhí)行環(huán)境是基于對象的,而作用域是基于函數(shù)的。 前述 在我們學(xué)習(xí)Javascript過程中,常常會(huì)遇到作用域(Scope)和執(zhí)行上下文(Context)等概念。其中,執(zhí)行上下文與this關(guān)鍵字的關(guān)系密切。 有面向?qū)ο缶幊探?jīng)驗(yàn)的各位,對于this關(guān)鍵字再熟悉不過了,因此...

    April 評論0 收藏0
  • Javascript this 一些學(xué)習(xí)總結(jié)02【轉(zhuǎn)自cnblogsJKhuang

    摘要:發(fā)生這種情況的條件是當(dāng)引用類型值的對象恰好為活躍對象。總結(jié)本文介紹中的使用,更重要的是幫助我們能更好地理解值在全局函數(shù)構(gòu)造函數(shù)以及一些特例的情況中值的變化。然而,由于對于來說沒有任何意義,因此會(huì)隱式轉(zhuǎn)換為全局對象。 接上一篇Javascript this 的一些學(xué)習(xí)總結(jié)02【轉(zhuǎn)自cnblogs的JKhuang】 引用類型以及this的null值 對于前面提及的情形,還有例外的情況,當(dāng)調(diào)...

    suemi 評論0 收藏0
  • 談?wù)?em>javascript插件寫法

    插件顧名思義就是能在一個(gè)頁面多處使用, 各自按自己的參數(shù)配置運(yùn)行, 并且相互不會(huì)沖突.會(huì)寫javascript插件是進(jìn)階js高級的必經(jīng)之路, 也是自己所學(xué)知識的一個(gè)典型的綜合運(yùn)用. 如果你還沒頭緒, 無從下手的話, 不用著急, 今天我們就一起來探討一下插件的一般寫法.所需技能: 1.面向?qū)ο笥梅?2.閉包的理解 3.變量作用域的理解 以一個(gè)tab選項(xiàng)卡的為例: 第一步: 我們需要寫html結(jié)...

    lakeside 評論0 收藏0
  • 深入理解JavaScript系列3:全面解析Module模式

    摘要:總結(jié)上面的大部分方式都可以互相組合使用的,一般來說如果要設(shè)計(jì)系統(tǒng),可能會(huì)用到松耦合擴(kuò)展,私有狀態(tài)和子模塊這樣的方式。 簡介 Module模式是JavaScript編程中一個(gè)非常通用的模式,一般情況下,大家都知道基本用法,本文嘗試著給大家更多該模式的高級使用方式。 首先我們來看看Module模式的基本特征: 模塊化,可重用 封裝了變量和function,和全局的namaspace不接觸...

    付倫 評論0 收藏0

發(fā)表評論

0條評論

Thanatos

|高級講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<