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

資訊專欄INFORMATION COLUMN

JS進(jìn)階(1) —— 人人都能懂的構(gòu)造函數(shù)

Blackjun / 2095人閱讀

摘要:構(gòu)造函數(shù)的執(zhí)行過程先說一點(diǎn)基本概念。只有當(dāng)一個(gè)函數(shù)以關(guān)鍵字來調(diào)用的時(shí)候,我們才能說它是一個(gè)構(gòu)造函數(shù)。構(gòu)造函數(shù)的返回值構(gòu)造函數(shù)執(zhí)行過程的最后一步是默認(rèn)返回。

大家都知道原型和原型鏈?zhǔn)?JavaScript 中最經(jīng)典的問題之一,而構(gòu)造函數(shù)又是原型和原型鏈的基礎(chǔ),所以先了解清楚構(gòu)造函數(shù)以及它的執(zhí)行過程可以更好地幫助我們學(xué)習(xí)原型和原型鏈的知識(shí)。

本文將從以下幾個(gè)方面來探討構(gòu)造函數(shù):

1.什么是構(gòu)造函數(shù)

2.為什么要使用構(gòu)造函數(shù)

3.構(gòu)造函數(shù)的執(zhí)行過程

4.構(gòu)造函數(shù)的返回值

1.什么是構(gòu)造函數(shù)

在 JavaScript 中,用 new 關(guān)鍵字來調(diào)用的函數(shù),稱為構(gòu)造函數(shù)。

2.為什么要使用構(gòu)造函數(shù)

學(xué)習(xí)每一個(gè)概念,不僅要知道它是什么,還要知道為什么,以及解決什么樣的問題。

舉個(gè)例子,我們要錄入一年級(jí)一班中每一位同學(xué)的個(gè)人信息,那么我們可以創(chuàng)建一些對(duì)象,比如:

var p1 = { name: "zs", age: 6, gender: "男", hobby: "basketball" };
var p2 = { name: "ls", age: 6, gender: "女", hobby: "dancing" };
var p3 = { name: "ww", age: 6, gender: "女", hobby: "singing" };
var p4 = { name: "zl", age: 6, gender: "男", hobby: "football" };
// ...

像上面這樣,我們可以把每一位同學(xué)的信息當(dāng)做一個(gè)對(duì)象來處理。但是,我們會(huì)發(fā)現(xiàn),我們重復(fù)地寫了很多無意義的代碼。比如 name、age、gender、hobby 。如果這個(gè)班上有60個(gè)學(xué)生,我們得重復(fù)寫60遍。

這個(gè)時(shí)候,構(gòu)造函數(shù)的優(yōu)勢就體現(xiàn)出來了。我們發(fā)現(xiàn),雖然每位同學(xué)都有 name、gender、hobby 這些屬性, 但它們都是不同的,那我們就把這些屬性當(dāng)做構(gòu)造函數(shù)的參數(shù)傳遞進(jìn)去。而由于都是一年級(jí)的學(xué)生,age 基本都是6歲,所以我們就可以寫死,遇到特殊情況再多帶帶做處理即可。此時(shí),我們就可以創(chuàng)建以下的函數(shù):

function Person(name, gender, hobby) {
    this.name = name;
    this.gender = gender;
    this.hobby = hobby;
    this.age = 6;
}

當(dāng)創(chuàng)建上面的函數(shù)以后, 我們就可以通過 new 關(guān)鍵字調(diào)用,也就是通過構(gòu)造函數(shù)來創(chuàng)建對(duì)象了。

var p1 = new Person("zs", "男", "basketball");
var p2 = new Person("ls", "女", "dancing");
var p3 = new Person("ww", "女", "singing");
var p4 = new Person("zl", "男", "football");
// ...

此時(shí)你會(huì)發(fā)現(xiàn),創(chuàng)建對(duì)象會(huì)變得非常方便。所以,雖然封裝構(gòu)造函數(shù)的過程會(huì)比較麻煩,但一旦封裝成功,我們?cè)賱?chuàng)建對(duì)象就會(huì)變得非常輕松,這也是我們?yōu)槭裁匆褂脴?gòu)造函數(shù)的原因。

在使用對(duì)象字面量創(chuàng)建一系列同一類型的對(duì)象時(shí),這些對(duì)象可能具有一些相似的特征(屬性)和行為(方法),此時(shí)會(huì)產(chǎn)生很多重復(fù)的代碼,而使用構(gòu)造函數(shù)就可以實(shí)現(xiàn)代碼的復(fù)用。

3.構(gòu)造函數(shù)的執(zhí)行過程

先說一點(diǎn)基本概念。

function Animal(color) {
  this.color = color;
}

當(dāng)一個(gè)函數(shù)創(chuàng)建好以后,我們并不知道它是不是構(gòu)造函數(shù),即使像上面的例子一樣,函數(shù)名為大寫,我們也不能確定。只有當(dāng)一個(gè)函數(shù)以 new 關(guān)鍵字來調(diào)用的時(shí)候,我們才能說它是一個(gè)構(gòu)造函數(shù)。就像下面這樣:

var dog = new Animal("black");

以下我們只討論構(gòu)造函數(shù)的執(zhí)行過程,也就是以 new 關(guān)鍵字來調(diào)用的情況。

我們還是以上面的 Person 為例。

function Person(name, gender, hobby) {
  this.name = name;
  this.gender = gender;
  this.hobby = hobby;
  this.age = 6;
}

var p1 = new Person("zs", "男", "basketball");

此時(shí),構(gòu)造函數(shù)會(huì)有以下幾個(gè)執(zhí)行過程:

(1) 當(dāng)以 new 關(guān)鍵字調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)新的內(nèi)存空間,標(biāo)記為 Animal 的實(shí)例。

(2) 函數(shù)體內(nèi)部的 this 指向該內(nèi)存

通過以上兩步,我們就可以得出這樣的結(jié)論。

var p2 = new Person("ls", "女", "dancing");  // 創(chuàng)建一個(gè)新的內(nèi)存 #f2
var p3 = new Person("ww", "女", "singing");  // 創(chuàng)建一個(gè)新的內(nèi)存 #f3

每當(dāng)創(chuàng)建一個(gè)實(shí)例的時(shí)候,就會(huì)創(chuàng)建一個(gè)新的內(nèi)存空間(#f2, #f3),創(chuàng)建 #f2 的時(shí)候,函數(shù)體內(nèi)部的 this 指向 #f2, 創(chuàng)建 #f3 的時(shí)候,函數(shù)體內(nèi)部的 this 指向 #f3。

(3) 執(zhí)行函數(shù)體內(nèi)的代碼

通過上面的講解,你就可以知道,給 this 添加屬性,就相當(dāng)于給實(shí)例添加屬性。

(4) 默認(rèn)返回 this

由于函數(shù)體內(nèi)部的 this 指向新創(chuàng)建的內(nèi)存空間,默認(rèn)返回 this ,就相當(dāng)于默認(rèn)返回了該內(nèi)存空間,也就是上圖中的 #f1。此時(shí),#f1的內(nèi)存空間被變量 p1 所接受。也就是說 p1 這個(gè)變量,保存的內(nèi)存地址就是 #f1,同時(shí)被標(biāo)記為 Person 的實(shí)例。

以上就是構(gòu)造函數(shù)的整個(gè)執(zhí)行過程。

4.構(gòu)造函數(shù)的返回值

構(gòu)造函數(shù)執(zhí)行過程的最后一步是默認(rèn)返回 this 。言外之意,構(gòu)造函數(shù)的返回值還有其它情況。下面我們就來聊聊關(guān)于構(gòu)造函數(shù)返回值的問題。

(1)沒有手動(dòng)添加返回值,默認(rèn)返回 this

function Person1() {
  this.name = "zhangsan";
}

var p1 = new Person1();

按照上面講的,我們復(fù)習(xí)一遍。首先,當(dāng)用 new 關(guān)鍵字調(diào)用時(shí),產(chǎn)生一個(gè)新的內(nèi)存空間 #f11,并標(biāo)記為 Person1 的實(shí)例;接著,函數(shù)體內(nèi)部的 this 指向該內(nèi)存空間 #f11;執(zhí)行函數(shù)體內(nèi)部的代碼;由于函數(shù)體內(nèi)部的 this 指向該內(nèi)存空間,而該內(nèi)存空間又被變量 p1 所接收,所以 p1 中就會(huì)有一個(gè) name 屬性,屬性值為 "zhangsan"。

p1: {
  name: "zhangsan"
}

(2) 手動(dòng)添加一個(gè)基本數(shù)據(jù)類型的返回值,最終還是返回 this

function Person2() {
  this.age = 28;
  return 50;
}

var p2 = new Person2();
console.log(p2.age);   // 28
p2: {
  age: 28
}

如果上面是一個(gè)普通函數(shù)的調(diào)用,那么返回值就是 50。

(3) 手動(dòng)添加一個(gè)復(fù)雜數(shù)據(jù)類型(對(duì)象)的返回值,最終返回該對(duì)象

直接上例子

function Person3() {
  this.height = "180";
  return ["a", "b", "c"];
}

var p3 = new Person3();
console.log(p3.height);  // undefined
console.log(p3.length);  // 3
console.log(p3[0]);      // "a"

再來一個(gè)例子

function Person4() {
  this.gender = "男";
  return { gender: "中性" };
}

var p4 = new Person4();
console.log(p4.gender);  // "中性"

關(guān)于構(gòu)造函數(shù)的返回值,無非就是以上幾種情況,大家可以動(dòng)手試一試,也就記住了。

最后總結(jié)一下,本文從四個(gè)方面介紹了構(gòu)造函數(shù),而構(gòu)造函數(shù)是原型和原型鏈學(xué)習(xí)的基礎(chǔ),所以大家有必要花點(diǎn)時(shí)間好好學(xué)習(xí)一下關(guān)于構(gòu)造函數(shù)的知識(shí),下篇文章我會(huì)來講講人人都能看懂的原型鏈,敬請(qǐng)期待。

最后的最后,我所說的不一定都對(duì),你一定要自己試試!

(本文完)

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

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

相關(guān)文章

  • 人人都能懂的Vue源碼系列—03—resolveConstructorOptions函數(shù)-上

    摘要:上篇文章介紹了構(gòu)造函數(shù)的部分實(shí)現(xiàn),當(dāng)前實(shí)例不是組件時(shí),會(huì)執(zhí)行方法。這個(gè)文件就是對(duì)構(gòu)造函數(shù)進(jìn)行的第一層包裝了。但是注意這里的代碼我們構(gòu)造函數(shù)的第二層包裝,就在這個(gè)文件里了?;氐降脑创a中,當(dāng)不存在時(shí),直接返回基礎(chǔ)構(gòu)造器的。 上篇文章介紹了Vue構(gòu)造函數(shù)的部分實(shí)現(xiàn),當(dāng)前Vue實(shí)例不是組件時(shí),會(huì)執(zhí)行mergeOptions方法。 vm.$options = mergeOptions( re...

    snifes 評(píng)論0 收藏0
  • 人人都能懂的Vue源碼系列—02—Vue構(gòu)造函數(shù)

    摘要:果然我們找到了的構(gòu)造函數(shù)定義。告訴你是一個(gè)構(gòu)造函數(shù),需要用操作符去調(diào)用。在深入方法之前,我們先把目光移到文件里在的構(gòu)造函數(shù)定義之后,有一系列方法會(huì)被立即調(diào)用。下篇博文主要介紹相關(guān)的內(nèi)容,涉及到原型鏈和構(gòu)造函數(shù)以及部分的實(shí)現(xiàn),敬請(qǐng)期待 上篇博文中說到了Vue源碼的目錄結(jié)構(gòu)是什么樣的,每個(gè)目錄的作用我們應(yīng)該也有所了解。我們知道core/instance目錄主要是用來實(shí)例化Vue對(duì)象,所以我...

    X_AirDu 評(píng)論0 收藏0
  • 人人都能懂的Vue源碼系列—01—Vue源碼目錄結(jié)構(gòu)

    摘要:閱讀的源碼,或者說閱讀一個(gè)框架的源碼,了解它的目錄結(jié)構(gòu)都是很有幫助的。人人都能懂的源碼系列文章將會(huì)詳細(xì)的介紹源碼的方方面面。 閱讀Vue的源碼,或者說閱讀一個(gè)框架的源碼,了解它的目錄結(jié)構(gòu)都是很有幫助的。下面我們來看看Vue源碼的目錄結(jié)構(gòu)。showImg(https://segmentfault.com/img/bV8fLS?w=598&h=654); Vue各目錄簡介 下圖是Vue各個(gè)...

    MAX_zuo 評(píng)論0 收藏0
  • 人人都能懂的Vue源碼系列—04—resolveConstructorOptions函數(shù)-下

    摘要:上一篇文章中說道,函數(shù)要分兩種情況進(jìn)行說明,第一種是為基礎(chǔ)構(gòu)造器的情況,這個(gè)已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況,是創(chuàng)建的子類。表示的是當(dāng)前構(gòu)造器上新增的,表示的是當(dāng)前構(gòu)造器上新增的封裝。 上一篇文章中說道,resolveConstructorOptions函數(shù)要分兩種情況進(jìn)行說明,第一種是Ctor為基礎(chǔ)構(gòu)造器的情況,這個(gè)已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況...

    My_Oh_My 評(píng)論0 收藏0
  • 人人都能懂的Vue源碼系列—04—resolveConstructorOptions函數(shù)-下

    摘要:上一篇文章中說道,函數(shù)要分兩種情況進(jìn)行說明,第一種是為基礎(chǔ)構(gòu)造器的情況,這個(gè)已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況,是創(chuàng)建的子類。表示的是當(dāng)前構(gòu)造器上新增的,表示的是當(dāng)前構(gòu)造器上新增的封裝。 上一篇文章中說道,resolveConstructorOptions函數(shù)要分兩種情況進(jìn)行說明,第一種是Ctor為基礎(chǔ)構(gòu)造器的情況,這個(gè)已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況...

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

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

0條評(píng)論

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