成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

理解 JavaScript(一)

longshengwang / 1962人閱讀

摘要:中的首先,是一個(gè)操作符,它可以用來創(chuàng)建兩種對(duì)象的實(shí)例,一種是用戶定義的對(duì)象類型,另一種則是擁有構(gòu)造函數(shù)的內(nèi)建對(duì)象類型。這就是原型繼承構(gòu)造函數(shù)被調(diào)用并傳入指定的參數(shù)示例二中的,然后被綁定給新創(chuàng)建的對(duì)象。

JavaScript 中的 new

首先,new 是一個(gè)操作符,它可以用來創(chuàng)建兩種對(duì)象的實(shí)例,一種是用戶定義的對(duì)象類型,另一種則是擁有構(gòu)造函數(shù)的內(nèi)建對(duì)象類型。

創(chuàng)建用戶定義的對(duì)象需要兩個(gè)步驟:

通過編寫函數(shù)來定義對(duì)象類型;

使用 new 來創(chuàng)建對(duì)象實(shí)例。


示例一:

var Person = function(personName) {
    this.name = personName;
};

這是一個(gè)典型的通過編寫函數(shù)來定義對(duì)象類型的范例,我們可以這樣來表述其行為:

  

Person 函數(shù)定義了一種對(duì)象類型,其 類型名稱 就叫 Person。
在使用 Person 函數(shù)創(chuàng)建對(duì)象實(shí)例的時(shí)候可以傳入變量 personName,該變量會(huì)成為對(duì)象實(shí)例的一個(gè)屬性,這個(gè)屬性的名字叫 name
為對(duì)象實(shí)例定義 name 屬性的過程發(fā)生在 Person 函數(shù)的函數(shù)體內(nèi);this 即指代將被創(chuàng)建的對(duì)象實(shí)例。

值得初學(xué)者注意的是,在現(xiàn)實(shí)中你更多地會(huì)看到這樣的代碼:

var Person = function(name) {
    this.name = name;
};

有些人會(huì)搞不清楚究竟哪一個(gè) name 才是對(duì)象的屬性,在這里詳細(xì)解釋如下:

function(name) 里的 name待傳入?yún)?shù)的名字,通常被稱作:形式參數(shù)(Formal Parameter),或簡(jiǎn)稱 形參 ——因?yàn)樗皇谴韰?shù)的形式而并非真正傳入的參數(shù)(后者則被稱作:實(shí)際參數(shù)(Actual Parameter),或簡(jiǎn)稱 實(shí)參)。

this.namename 是對(duì)象的屬性名字。

= namename 還是形參,和 1. 里的 name 等價(jià);這就是所謂的 參數(shù)傳遞,或傳參。


示例二:

var albert = new Person("Albert");
albert.name;       // "Albert"
albert["name"];    // "Albert"

這是承接示例一,使用定義好的 Person 對(duì)象類型來實(shí)例化對(duì)象的范例,這個(gè)范例的表述相對(duì)容易一些:

  

定義一個(gè)變量 albert,然后實(shí)例化一個(gè)新的 Person 類型的對(duì)象,并將變量 albert 指向這個(gè)新的對(duì)象。

如果你對(duì) 形參實(shí)參 還不夠清楚的話,看到這里就應(yīng)該完全明了了。保險(xiǎn)起見再加以解釋如下:

在示例二中,new Person("Albert") 中的 "Albert" 即對(duì)應(yīng)著示例一中 function(name) 中的 name,同時(shí)也是接下來一行中等號(hào)右邊的 name。

因此,"Albert" 就是 實(shí)際參數(shù),name 就是 形式參數(shù)。

示例二中還演示了兩種對(duì)象屬性的獲取方法,分別為 object.propertyobject["property"]。前一種比較常用,不過后一種由于可以用字符串來訪問對(duì)象屬性,因此在某些場(chǎng)合下非常有用(比如說用字符串傳遞了對(duì)象的屬性)。


回到 new 的話題。

當(dāng) new Person("Albert") 執(zhí)行的時(shí)候,會(huì)有如下事情發(fā)生:

創(chuàng)建一個(gè)新的對(duì)象,其類型是 Person 并繼承 Person.prototype 的所有屬性。這就是 原型繼承;

構(gòu)造函數(shù) Person 被調(diào)用并傳入指定的參數(shù)(示例二中的 "Albert"),然后 this 被綁定給新創(chuàng)建的對(duì)象。另外,若構(gòu)造函數(shù)不需要參數(shù),則 new Person 等價(jià)于 new Person();

若構(gòu)造函數(shù)沒有明確的返回值,那么新創(chuàng)建的對(duì)象就是整個(gè) new 表達(dá)式的結(jié)果;反之,若構(gòu)造函數(shù)內(nèi)顯式定義了返回值,則該返回值為整個(gè) new 表達(dá)式的結(jié)果。

關(guān)于第三點(diǎn),舉例示之:

示例三:

var Person = function(name) {
    return {
        name: "Mr. " + name
    }
};

var albert = new Person("Albert");

albert.name;        // "Mr. Albert"
var Person = function(name) {
    return {
        rawName: name,
        getName: function(gender) {
            if (gender === "male") {
                return "Mr. " + name;
            } else {
                return "Mrs. " + name;
            }
        }
    }
};

var albert = new Person("Albert");

albert.getName("male");        // "Mr. Albert"
albert.getName("female");      // "Mrs. Albert"
var Person = function(name, gender) {
    return {
        rawName: name,
        name: (function() {
            if (gender === "male") {
                return "Mr. " + name;
            } else {
                return "Mrs. " + name;
            }
        }())
    }
};

var albert = new Person("Albert", "male");
albert.rawName;             // "Albert"
albert.name;                // "Mr. Albert"

var annie = new Person("Annie", "female");
annie.rawName;              // "Annie"
annie.name;                 // "Mrs. Annie"

示例三演示了三種看起來相似但實(shí)際上具有顯著差異的對(duì)象類型定義和對(duì)象實(shí)例化的例子:

第一種:在 new Person("Albert") 時(shí)返回自定義的對(duì)象,而不是默認(rèn)由 new 創(chuàng)建的新對(duì)象。在這個(gè)自定義對(duì)象里,沒有簡(jiǎn)單地把參數(shù) name 賦給屬性 this.name,而是做了進(jìn)一步的修改。這種修改很顯然是非常簡(jiǎn)單但卻不夠靈活,為了改進(jìn)它,看下面兩個(gè)例子:

第二種:同樣返回自定義對(duì)象,這一次定義了兩個(gè)屬性,一個(gè)是 rawName,保存實(shí)例化時(shí)傳遞的參數(shù);另一個(gè)是 getName,它是一個(gè)函數(shù)聲明,因此不能直接用 albert.getNamealbert["getName"] 來訪問(只會(huì)返回函數(shù)聲明本身,但不會(huì)有返回值)。不過你可以用albert.getNam("male")albert["getName"]("male") 的方式來執(zhí)行這個(gè)函數(shù)并求得結(jié)果,這就是所謂的 方法
如果不想用方法調(diào)用,但仍然希望像方法聲明體內(nèi)那樣做一些邏輯判斷是否可以呢?可以,繼續(xù)看第三種:

第三種:這一次 name 屬性又可以像以前那樣直接訪問了,原因是 name 指向的函數(shù)聲明使用了 IIFE(Immediately Invoked Function Expression) 技巧,該技巧使得函數(shù)聲明直接轉(zhuǎn)變成了函數(shù)表達(dá)式(并即刻執(zhí)行)。我們知道,函數(shù)表達(dá)式是能夠直接返回值的,而函數(shù)聲明則需要執(zhí)行(調(diào)用)才能返回值,于是 name 屬性獲得了返回值,就可以像原來那樣直接訪問了。
這種屬性定義方式有時(shí)被稱之為 計(jì)算后屬性(Computed Property),顧名思義:不是直接返回實(shí)例化時(shí)傳遞的值,而是對(duì)值進(jìn)行了一定的處理(計(jì)算)之后才返回。


  

屬性與方法:很多人都以為對(duì)象有 屬性方法,其中屬性是可以直接訪問到值的,而方法是需要執(zhí)行才能獲得值的。但有的時(shí)候也會(huì)聽到“方法也是屬性”這樣的說法,這是為什么呢?
其實(shí)原因在于對(duì)術(shù)語的翻譯不夠準(zhǔn)確。英文里的 propertyattribute 都被我們翻譯為屬性,然而在談及對(duì)象時(shí)這兩者是不同的。在一個(gè)對(duì)象里,attributemethod 被統(tǒng)稱為 property,直接保存值的 property 稱之為 attribute,保存函數(shù)聲明可以用來執(zhí)行的 property 才是 method。在用中文描述時(shí)很容易把兩種“屬性”搞混,需要注意分辨清楚。

補(bǔ)充說明:本文發(fā)表出去之后,有人感謝我?guī)退智辶?屬性方法 在一些書中的歧義性,也有人拿著別的書來向我表示疑惑。以再版的 Object Oriented in JavaScript 為例,該書中在講解面向?qū)ο蠡A(chǔ)的時(shí)候,明確地指出:保存數(shù)據(jù)的屬性叫做 Property,保存行為的屬性叫做 Method,根本就不使用 Attribute。這倒是也簡(jiǎn)單明了,這樣一來就不存在 Method 也是 Property 一說了。

老實(shí)說,對(duì)此我也不知該如何回應(yīng)。不同的書用不同的術(shù)語,不同的作者也有不同的理解,我沒有“統(tǒng)一業(yè)界術(shù)語”的能量,所以也只能把它們一一列舉出來。對(duì)于初學(xué)者若造成理解上的偏差我表示道歉,總而言之你要記?。?strong>一個(gè)對(duì)象有兩類東西:一類記錄數(shù)據(jù),另一類記錄方法(方法總是做一件什么事,其中也包括返回新的數(shù)據(jù)),至于這兩類在不同的情境中叫法不一,也就要靠你自己去分辨了。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77968.html

相關(guān)文章

  • 名【合格】前端工程師的自檢清單

    摘要:在他的重學(xué)前端課程中提到到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系中的重要崗位之一。大部分前端工程師的知識(shí),其實(shí)都是來自于實(shí)踐和工作中零散的學(xué)習(xí)。一基礎(chǔ)前端工程師吃飯的家伙,深度廣度一樣都不能差。 開篇 前端開發(fā)是一個(gè)非常特殊的行業(yè),它的歷史實(shí)際上不是很長(zhǎng),但是知識(shí)之繁雜,技術(shù)迭代速度之快是其他技術(shù)所不能比擬的。 winter在他的《重學(xué)前端》課程中提到: 到現(xiàn)在為止,前端工程師已經(jīng)成為研...

    羅志環(huán) 評(píng)論0 收藏0
  • 名【合格】前端工程師的自檢清單

    摘要:在他的重學(xué)前端課程中提到到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系中的重要崗位之一。大部分前端工程師的知識(shí),其實(shí)都是來自于實(shí)踐和工作中零散的學(xué)習(xí)。一基礎(chǔ)前端工程師吃飯的家伙,深度廣度一樣都不能差。開篇 前端開發(fā)是一個(gè)非常特殊的行業(yè),它的歷史實(shí)際上不是很長(zhǎng),但是知識(shí)之繁雜,技術(shù)迭代速度之快是其他技術(shù)所不能比擬的。 winter在他的《重學(xué)前端》課程中提到: 到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系...

    isaced 評(píng)論0 收藏0
  • 理解javascript核心知識(shí)點(diǎn)

    摘要:作用域鏈的作用就是做標(biāo)示符解析。事件循環(huán)還有個(gè)明顯的特點(diǎn)單線程。早期都是用作開發(fā),單線程可以比較好當(dāng)規(guī)避同步問題,降低了開發(fā)門檻。單線程需要解決的是效率問題,里的解決思想是異步非阻塞。 0、前言 本人在大學(xué)時(shí)非常癡迷java,認(rèn)為java就是世界上最好的語言,偶爾在項(xiàng)目中會(huì)用到一些javascript,但基本沒放在眼里。較全面的接觸javascript是在實(shí)習(xí)的時(shí)候,通過這次的了解發(fā)現(xiàn)...

    laznrbfe 評(píng)論0 收藏0
  • JavaScript 異步

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過...

    tuniutech 評(píng)論0 收藏0
  • 前端練級(jí)攻略(第二部分)

    摘要:是文檔的一種表示結(jié)構(gòu)。這些任務(wù)大部分都是基于它。這個(gè)實(shí)踐的重點(diǎn)是把你在前端練級(jí)攻略第部分中學(xué)到的一些東西和結(jié)合起來。一旦你進(jìn)入框架部分,你將更好地理解并使用它們。到目前為止,你一直在使用進(jìn)行操作。它是在前端系統(tǒng)像今天這樣復(fù)雜之前編寫的。 本文是 前端練級(jí)攻略 第二部分,第一部分請(qǐng)看下面: 前端練級(jí)攻略(第一部分) 在第二部分,我們將重點(diǎn)學(xué)習(xí) JavaScript 作為一種獨(dú)立的語言,如...

    BWrong 評(píng)論0 收藏0
  • 前端基礎(chǔ)進(jìn)階():內(nèi)存空間詳細(xì)圖解

    摘要:一棧數(shù)據(jù)結(jié)構(gòu)與不同,中并沒有嚴(yán)格意義上區(qū)分棧內(nèi)存與堆內(nèi)存。引用數(shù)據(jù)類型的值是保存在堆內(nèi)存中的對(duì)象。不允許直接訪問堆內(nèi)存中的位置,因此我們不能直接操作對(duì)象的堆內(nèi)存空間。為了更好的搞懂變量對(duì)象與堆內(nèi)存,我們可以結(jié)合以下例子與圖解進(jìn)行理解。 showImg(https://segmentfault.com/img/remote/1460000009784102?w=1240&h=683); ...

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

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

0條評(píng)論

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