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

資訊專欄INFORMATION COLUMN

JavaScript學(xué)習(xí)筆記(二) 對(duì)象與函數(shù)

jeffrey_up / 2303人閱讀

摘要:在中函數(shù)是一等對(duì)象,它們不被聲明為任何東西的一部分,而所引用的對(duì)象稱為函數(shù)上下文并不是由聲明函數(shù)的方式?jīng)Q定的,而是由調(diào)用函數(shù)的方式?jīng)Q定的。更為準(zhǔn)確的表述應(yīng)該為當(dāng)對(duì)象充當(dāng)函數(shù)的調(diào)用函數(shù)上下文時(shí),函數(shù)就充當(dāng)了對(duì)象的方法。

  

引言:當(dāng)理解了對(duì)象和函數(shù)的基本概念,你可能會(huì)發(fā)現(xiàn),在JavaScript中有很多原以為理所當(dāng)然(或盲目接受)的事情開始變得更有意義了。

1.JavaScript對(duì)象

大多數(shù)面向?qū)ο螅ê?jiǎn)稱OO)語(yǔ)言都定義了某種基本的Object對(duì)象類型,其它所有的對(duì)象都源于這個(gè)對(duì)象類型。

JavaScript的基本對(duì)象也是作為其它對(duì)象的基礎(chǔ),但是從基本層面上來(lái)看,JavaScript的Object對(duì)象與其它大部分的OO語(yǔ)言所定義的基本對(duì)象很不同。

對(duì)象一旦被創(chuàng)建后,它不保存任何數(shù)據(jù)并且?guī)缀鯖]有什么語(yǔ)義。但是這些有限的語(yǔ)義的確又給予了它很大的潛力。

新的對(duì)象由new操作符和與其相配的Object構(gòu)造器來(lái)產(chǎn)生。創(chuàng)建一個(gè)對(duì)象非常簡(jiǎn)單:

var shinyAndNew = new Object();    // 還可以更簡(jiǎn)單

這個(gè)新對(duì)象能做什么?似乎什么也沒有——沒有信息,沒有復(fù)雜的語(yǔ)義,什么也沒有,一點(diǎn)也不吸引人,直到我們開始向其添加稱為 屬性 的東西。

JavaScript Object的實(shí)例(即:對(duì)象)就是一組屬性集,每個(gè)屬性都由名稱和值構(gòu)成。屬性的名稱是字符串,屬性值可以是任何JavaScript對(duì)象,可以是Number、String、Date、Array、基本的Object,也可以是任何其它的JavaScript對(duì)象類型(例如函數(shù))。

這意味著Object實(shí)例的主要就是用作容器,包含其它對(duì)象的已命名集合。進(jìn)一步,一個(gè)對(duì)象屬性可以是另一個(gè)Object實(shí)例,這個(gè)實(shí)例又包含其它自己的屬性集,而屬性集也可以包含擁有屬性的對(duì)象,以此類推。只要對(duì)我們塑造的數(shù)據(jù)模型有意義,就可以嵌套至任何層次。

舉個(gè)栗子:
假設(shè)給一輛車(car)添加一個(gè)新的屬性以保存車輛的所有者(owner)信息。這個(gè)屬性是另一個(gè)JavaScript對(duì)象,它包含了一些屬性,如所有者姓名和職業(yè):

var owner = new Object();
owner.name = "Roger Shieh";
owner.occupation = "Coder";
car.owner = owner;

為了訪問嵌套的屬性,我們可以編寫如下代碼:

var ownerName = car.owner.name;
  

提示:出于解釋的目的而創(chuàng)建的所有中間變量都是可以省略的(比如owner)。于是,我們可以利用這一點(diǎn)來(lái)使用更加高效和簡(jiǎn)潔的方式來(lái)聲明對(duì)象及其屬性的代碼。

我們使用點(diǎn)操作符(英文的句號(hào)字符)來(lái)引用對(duì)象的屬性。但是事實(shí)證明,有一個(gè)更加通用的操作符來(lái)執(zhí)行屬性的引用。

通用的屬性引用操作符的格式:

object[propertyNameExpression]

其中propertyNameExpression是JavaScript表達(dá)式,其求值的結(jié)果作為要引用的屬性名稱的字符串。

例如,下面的3個(gè)引用都是等價(jià)的:

car.color    // 第1種
car["color"]    // 第2種
car["c"+"o"+"l"+"o"+"r"]    // 第3種
var p = "color"; car[p]    // 第4種

對(duì)于其名稱并非有效的JavaScript標(biāo)識(shí)符的屬性來(lái)說(shuō),使用通用的引用操作符是引用這種屬性的唯一方法,例如:

car["a property name that"s rather odd!"]

我們通過new操作符來(lái)創(chuàng)建新的實(shí)例,并且利用獨(dú)立的賦值語(yǔ)句來(lái)為每個(gè)屬性賦值從而建立對(duì)象,這看起來(lái)是一件繁瑣的事情。而且,這樣做既枯燥乏味,又冗長(zhǎng)易錯(cuò),難以在快速檢查代碼的時(shí)候把握對(duì)象的結(jié)構(gòu)

幸運(yùn)的是,我們可以使用更緊湊和更易于閱讀的表示法。參考如下語(yǔ)句:

var car = {
    make:"Ford",
    year:2014,
    purchased:new Date(2014,12,3),
    owner:{
        name:"Roger Shieh",
        occupation:"Coder"
    }
};

這種表示法被稱為 JSON(JavaScript Object Notaition,JavaScript對(duì)象表示法)。大多數(shù)頁(yè)面開發(fā)者對(duì)JSON的偏愛有加,不喜歡通過多個(gè)賦值語(yǔ)句來(lái)建立對(duì)象的方式。

至此,我們看到了兩種保存JavaScript對(duì)象的方式:變量和屬性

這兩種保存引用的方式使用不同的表示法,如下所示:

var aVariable = "Before I teamed up with you, I led quite a normal life.";

someObject.aProperty = "You move that line as you see fit for yourself.";

事實(shí)上,這個(gè)兩個(gè)語(yǔ)句在執(zhí)行相同的操作。

任何在頂層作用域中生成的引用都隱式地創(chuàng)建在window實(shí)例中。

比如下面的語(yǔ)句,如果是在頂層中(也就是在函數(shù)的作用域之外)生成的,那么它們都是等價(jià)的:

var foo = bar;

window.foo = bar;

foo = bar;

不管使用的是哪種表示法,都會(huì)創(chuàng)建一個(gè)名為foowindow屬性(如果foo屬性尚未存在),并且將bar賦值給foo。還要注意,因?yàn)?b>bar是非限定的,所以將其假定為window的一個(gè)屬性。

把頂層作用域認(rèn)為是window作用域,這可能不會(huì)讓我們陷入概念上的煩惱,因?yàn)槿魏挝挥陧攲拥奈聪薅ǖ囊枚急患俣閣indow的屬性

重要概念總結(jié)如下:

JavaScript對(duì)象是屬性的無(wú)序集合;

屬性由名稱和值組成;

可以使用字面值來(lái)聲明對(duì)象;

頂層變量是window的屬性。

2.作為一等公民的函數(shù)
  

當(dāng)我們談到JavaScript函數(shù)是一等對(duì)象時(shí),意味著什么?

在許多傳統(tǒng)的OO語(yǔ)言中,對(duì)象可以包含數(shù)據(jù),還可以擁有方法。在這些語(yǔ)言中,數(shù)據(jù)和方法通常是不同的概念。

JavaScript可不是這樣子。

JavaScript中的函數(shù)也被認(rèn)為是對(duì)象,與定義在JavaScript中任何其它的對(duì)象類型一樣,比如StringNumberDate

和其它對(duì)象一樣,函數(shù)也是通過JavaScript構(gòu)造器來(lái)定義的(在這種情況下是Function),可以對(duì)函數(shù)進(jìn)行如下操作:

把函數(shù)賦值給變量;

將函數(shù)指定為一個(gè)對(duì)象的屬性;

把函數(shù)作為參數(shù)傳遞;

把函數(shù)作為函數(shù)結(jié)果返回;

使用字面值來(lái)創(chuàng)建函數(shù)。

因?yàn)樵贘avaScript語(yǔ)言中對(duì)待函數(shù)的方式與對(duì)待其它對(duì)象的方式相同,所以我們說(shuō)函數(shù)是一等對(duì)象

與對(duì)象的其它實(shí)例(例如StringDateNumber)一樣,只有在把函數(shù)賦值給變量、屬性或參數(shù)的時(shí)候,函數(shù)才能被引用。

我們經(jīng)常通過字面值表示法來(lái)表示Number實(shí)例,例如下面的語(yǔ)句:

213;

完全有效,但同時(shí)完全無(wú)用。Number實(shí)例用處不大,除非將其賦值給屬性或?qū)ο螅蛘邔⑵浣壎ǖ絽?shù)名稱上。否則,我們無(wú)法引用散落在內(nèi)存中的實(shí)例。

同樣的規(guī)則也適用于Function對(duì)象的實(shí)例。

思考下面的代碼:

// 這不是創(chuàng)建了名為doSomethingWonderful的函數(shù)嗎?
function doSomethingWonderful(){
    alert("does something wonderful"); 
}

盡管這種表示法可能看起來(lái)很熟悉,而且被廣泛用來(lái)創(chuàng)建頂層函數(shù),但它與通過var來(lái)創(chuàng)建window屬性使用的是相同的語(yǔ)法。

function關(guān)鍵字自動(dòng)創(chuàng)建一個(gè)Function實(shí)例并將其賦值給使用函數(shù)“名稱”創(chuàng)建的window屬性,如下所示:

doSomethingWonderful = function(){
    alert("does something wonderful");
}

如果看起來(lái)覺得奇怪,考慮另一個(gè)使用完全相同形式的語(yǔ)句,但這次使用Number的字面值:

aWonderfulNumber = 213;

這個(gè)語(yǔ)句不足為奇,它與把函數(shù)賦值給頂層變量(window屬性)的語(yǔ)句如出一轍。

  

函數(shù)字面值表示法:由關(guān)鍵字function與緊接著的被圓括號(hào)所包含的參數(shù)列表,以及隨后的函數(shù)主體所組成。

記住,在HTML頁(yè)面中創(chuàng)建了頂層變量時(shí),會(huì)將變量創(chuàng)建為window實(shí)例的屬性。因此,下面的語(yǔ)句都是等價(jià)的:

function hello(){alert("wow!");}

hello = function(){alert("wow!");}

window.hello = function(){alert("wow!")}

理解這一點(diǎn)很重要:和其它對(duì)象類型的實(shí)例一樣,Function實(shí)例可以賦值給變量、屬性或參數(shù)的值。并且就像其它的那些對(duì)象類型,無(wú)名稱無(wú)實(shí)體的實(shí)例毫無(wú)用處,只有將它們賦值給變量、屬性或參數(shù),這樣才能引用它們

2.1 作為回調(diào)的函數(shù)。
function hello(){alert("Hey,guy!");}

setTimeout(hello, 5000);

當(dāng)計(jì)時(shí)器過期時(shí),hello函數(shù)會(huì)被調(diào)用。因?yàn)樵诖a中setTimeout()方法回調(diào)了一個(gè)函數(shù),所以該函數(shù)被稱為回調(diào)函數(shù)。

大部分高級(jí)JavaScript程序員可能會(huì)覺得這段代碼示例很幼稚,因?yàn)闆]有必要?jiǎng)?chuàng)建hello名稱。除非要在頁(yè)面的其它地方調(diào)用此函數(shù),否則沒有必要?jiǎng)?chuàng)建window的屬性hello來(lái)暫時(shí)存儲(chǔ)Function實(shí)例,以便將hello作為回調(diào)參數(shù)來(lái)傳遞。

所以,編寫這個(gè)片段更簡(jiǎn)潔的方式是:

setTimeout(function(){alert("Hey,guy!")},5000);

目前為止,示例中所創(chuàng)建額函數(shù)要么是頂層函數(shù)(也就是頂層的window屬性),要么是在函數(shù)調(diào)用中被賦值給參數(shù)。我們也可以將Function實(shí)例賦值給對(duì)象的屬性,此時(shí)事情才真正變得有趣起來(lái)。

2.2 this到底是什么
  

OO語(yǔ)言自動(dòng)提供了從方法中引用對(duì)象當(dāng)前實(shí)例的辦法。在Java和C++這樣的語(yǔ)言中,this參數(shù)指向當(dāng)前實(shí)例。

JavaScript實(shí)現(xiàn)中的this和其它OO語(yǔ)言中的this的差異體現(xiàn)在幾個(gè)重要的方面。

在JavaScript中函數(shù)是一等對(duì)象,它們不被聲明為任何東西的一部分,而this所引用的對(duì)象(稱為函數(shù)上下文)并不是由聲明函數(shù)的方式?jīng)Q定的,而是由調(diào)用函數(shù)的方式?jīng)Q定的。

在默認(rèn)情況下,函數(shù)調(diào)用的上下文(this)是對(duì)象,其屬性包含用于調(diào)用該函數(shù)的引用。

頂層函數(shù)是window的屬性,因此當(dāng)將其作為頂層函數(shù)來(lái)調(diào)用時(shí),其函數(shù)上下文就是window對(duì)象。

盡管這可能是常見的隱式行為,但是JavaScript提供的辦法可以顯式地控制函數(shù)上下文設(shè)置為任何想要的內(nèi)容。通過Function的方法call()apply()來(lái)調(diào)用函數(shù),就可以將函數(shù)上下文設(shè)置為任何想要的內(nèi)容(是的,作為一等對(duì)象,函數(shù)甚至擁有Function構(gòu)造器定義的那些方法)。

  

提示:使用call()方法來(lái)調(diào)用函數(shù),指定第一個(gè)參數(shù)作為函數(shù)上下文的對(duì)象,而其余參數(shù)稱為被調(diào)用函數(shù)的參數(shù);apply方法的工作方式與此類似,不同的是,它的第二個(gè)參數(shù)應(yīng)該成為被調(diào)用函數(shù)參數(shù)的對(duì)象數(shù)組。

下面的代碼將說(shuō)明函數(shù)上下文的值取決于調(diào)用函數(shù)的方式




    
    What"s this
    







從上面的示例頁(yè)面表明了:函數(shù)上下文是基于每個(gè)調(diào)用來(lái)決定的,可以使用任何對(duì)象作為函數(shù)上下文來(lái)調(diào)用單個(gè)函數(shù)。因此,“函數(shù)是對(duì)象的方法”這個(gè)說(shuō)法是絕對(duì)不正確的

更為準(zhǔn)確的表述應(yīng)該為:

  

當(dāng)對(duì)象o充當(dāng)函數(shù)f的調(diào)用函數(shù)上下文時(shí),函數(shù)f就充當(dāng)了對(duì)象o的方法。

既然已經(jīng)理解了函數(shù)如何充當(dāng)對(duì)象的方法,下面就來(lái)把注意力轉(zhuǎn)移到另一個(gè)高級(jí)的函數(shù)話題——閉包。

2.3 閉包
  

閉包就是Function實(shí)例,它結(jié)合了來(lái)自環(huán)境的(函數(shù)執(zhí)行所必需的)局部變量。

在聲明函數(shù)時(shí),可以在聲明函數(shù)時(shí)引用函數(shù)作用域內(nèi)任何變量。對(duì)于任何有技術(shù)背景的開發(fā)者來(lái)說(shuō),這是理所當(dāng)然的事情。但是使用閉包時(shí),即使在函數(shù)聲明之后,已經(jīng)超出函數(shù)作用域(也就是關(guān)閉了函數(shù)聲明)的情況下,該函數(shù)仍然帶有這些變量。

閱讀下面的栗子:




    
    Closure Example
    
    


    

在運(yùn)行這個(gè)頁(yè)面時(shí),如果我們不熟悉閉包去查看這段代碼,我們會(huì)覺得有點(diǎn)問題,可能會(huì)猜測(cè):因?yàn)榛卣{(diào)會(huì)在頁(yè)面加載后3秒觸發(fā)(在就緒處理器執(zhí)行完畢很久以后),所以local的值在回調(diào)函數(shù)的執(zhí)行期間是未定義的。畢竟,local聲明所在的塊在就緒處理器執(zhí)行完畢時(shí)超出了作用域,對(duì)吧?

然而,當(dāng)我們運(yùn)行時(shí)發(fā)現(xiàn)它能正常運(yùn)行!

  

閉包允許回調(diào)訪問環(huán)境中的值,即使該環(huán)境已經(jīng)超出了作用域。

當(dāng)就緒處理器執(zhí)行完畢,local聲明所在的塊超出了作用域,但是函數(shù)聲明所創(chuàng)建的閉包(包括local變量)在函數(shù)的生命周期內(nèi)都保持在作用域中。

  

注意:在JavaScript中的閉包,其創(chuàng)建方式都是隱式的,而不像其它一些支持閉包的語(yǔ)言那樣需要顯示的語(yǔ)法。這是一把雙刃劍,一方面使得創(chuàng)建閉包很容易,但另一個(gè)方面這使得很難在代碼中發(fā)現(xiàn)閉包。

無(wú)意創(chuàng)建的閉包可能會(huì)帶來(lái)意料之外的結(jié)果。例如,循環(huán)引用可能導(dǎo)致內(nèi)存泄露。內(nèi)存泄露的典型示例就是創(chuàng)建后引用閉包中變量的DOM元素,這會(huì)阻止那些變量的回收。

閉包的另一重要特征是:函數(shù)上下文絕不會(huì)被包含為閉包的一部分

閱讀下面這段代碼:

this.id = `someID`;
$("*").each(function(){
    alert(this id);
});    // 這段代碼不會(huì)按照我們期望的方式執(zhí)行

如果需要訪問在外部函數(shù)中作為函數(shù)上下文的對(duì)象,可以采用通常的習(xí)慣用法:在局部變量中創(chuàng)建this引用的副本,這個(gè)副本將會(huì)被包含在閉包中

于是,考慮如下改變:

this.id = "someID";
var outer = this;
$("*").each(function(){
    alert(this id);
});

局部變量outer被賦值為外部函數(shù)的函數(shù)上下文的引用,從而成為閉包的一部分,可以在回調(diào)函數(shù)中訪問此變量。改變后的代碼現(xiàn)在會(huì)彈出顯示字符串someID,包裝集($("*"))中有多少個(gè)元素就彈出多少次。

當(dāng)使用jQuery命令(這些命令利用異步的回調(diào)函數(shù))來(lái)創(chuàng)建優(yōu)雅的代碼時(shí),我們將會(huì)發(fā)現(xiàn)閉包是必不可少的,尤其是在Ajax請(qǐng)求和事件處理領(lǐng)域。

參考資料

jQuery實(shí)戰(zhàn)(第2版)

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85427.html

相關(guān)文章

  • javascript高程3 學(xué)習(xí)筆記()

    摘要:的理解函數(shù)與其他語(yǔ)言函數(shù)最大的不同在于,其不介意傳入多少參數(shù)以及參數(shù)的類型比如函數(shù)的形參有兩個(gè),但是調(diào)用函數(shù)傳入的參數(shù)可以寫一個(gè),三個(gè)或不寫參數(shù)對(duì)應(yīng)等,解析器都可以正常解析,這是因?yàn)橹袇?shù)在內(nèi)部是以一個(gè)數(shù)組形式來(lái)表示,故而不需要關(guān)系傳入?yún)?shù) ECMAScript function的理解 ECMAScript 函數(shù)與其他語(yǔ)言函數(shù)最大的不同在于,其不介意傳入多少參數(shù)以及參數(shù)的類型...

    JerryWangSAP 評(píng)論0 收藏0
  • JavaScript學(xué)習(xí)筆記之?dāng)?shù)組(

    摘要:方法用于刪除原數(shù)組的一部分成員,并可以在刪除的位置添加新的數(shù)組成員,返回值是被刪除的元素。,這兩個(gè)方法,返回一個(gè)布爾值,表示判斷數(shù)組成員是否符合某種條件。該函數(shù)接受三個(gè)參數(shù)當(dāng)前成員當(dāng)前位置和整個(gè)數(shù)組,然后返回一個(gè)布爾值。 數(shù)組基礎(chǔ)篇二 數(shù)組對(duì)象 1.聲明數(shù)組的方法 Array是 JavaScript 的原生對(duì)象,同時(shí)也是一個(gè)構(gòu)造函數(shù),可以用它生成新的數(shù)組。 var arr =new A...

    YPHP 評(píng)論0 收藏0
  • 對(duì)象管理器(defineProperty)學(xué)習(xí)筆記

    摘要:通過設(shè)置我們可以將一些屬性鎖定,來(lái)防止別人的修改,這是一種防御編程形式,就像語(yǔ)言的內(nèi)置對(duì)象一樣不過的內(nèi)置對(duì)象都可以被隨意更改。可以使用來(lái)判斷某一個(gè)屬性是否可以枚舉。 對(duì)象管理器(defineProperty) 在 JavaScript 里面聲明一個(gè)變量,通常我們有三種方式可以實(shí)現(xiàn): let person = {} // 對(duì)象字面量 let cat = new Objec...

    mist14 評(píng)論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記(七)--JavaScript對(duì)象:面向對(duì)象還是基于對(duì)象

    摘要:對(duì)象有狀態(tài)對(duì)象具有狀態(tài),同一對(duì)象可能處于不同狀態(tài)之下。中對(duì)象獨(dú)有的特色對(duì)象具有高度的動(dòng)態(tài)性,這是因?yàn)橘x予了使用者在運(yùn)行時(shí)為對(duì)象添改狀態(tài)和行為的能力。小結(jié)由于的對(duì)象設(shè)計(jì)跟目前主流基于類的面向?qū)ο蟛町惙浅4螅瑢?dǎo)致有不是面向?qū)ο筮@樣的說(shuō)法。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過程的一些...

    yy736044583 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

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