摘要:構造函數的執行過程先說一點基本概念。只有當一個函數以關鍵字來調用的時候,我們才能說它是一個構造函數。構造函數的返回值構造函數執行過程的最后一步是默認返回。
大家都知道原型和原型鏈是 JavaScript 中最經典的問題之一,而構造函數又是原型和原型鏈的基礎,所以先了解清楚構造函數以及它的執行過程可以更好地幫助我們學習原型和原型鏈的知識。
本文將從以下幾個方面來探討構造函數:
1.什么是構造函數
2.為什么要使用構造函數
3.構造函數的執行過程
4.構造函數的返回值
1.什么是構造函數在 JavaScript 中,用 new 關鍵字來調用的函數,稱為構造函數。
2.為什么要使用構造函數學習每一個概念,不僅要知道它是什么,還要知道為什么,以及解決什么樣的問題。
舉個例子,我們要錄入一年級一班中每一位同學的個人信息,那么我們可以創建一些對象,比如:
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" }; // ...
像上面這樣,我們可以把每一位同學的信息當做一個對象來處理。但是,我們會發現,我們重復地寫了很多無意義的代碼。比如 name、age、gender、hobby 。如果這個班上有60個學生,我們得重復寫60遍。
這個時候,構造函數的優勢就體現出來了。我們發現,雖然每位同學都有 name、gender、hobby 這些屬性, 但它們都是不同的,那我們就把這些屬性當做構造函數的參數傳遞進去。而由于都是一年級的學生,age 基本都是6歲,所以我們就可以寫死,遇到特殊情況再多帶帶做處理即可。此時,我們就可以創建以下的函數:
function Person(name, gender, hobby) { this.name = name; this.gender = gender; this.hobby = hobby; this.age = 6; }
當創建上面的函數以后, 我們就可以通過 new 關鍵字調用,也就是通過構造函數來創建對象了。
var p1 = new Person("zs", "男", "basketball"); var p2 = new Person("ls", "女", "dancing"); var p3 = new Person("ww", "女", "singing"); var p4 = new Person("zl", "男", "football"); // ...
此時你會發現,創建對象會變得非常方便。所以,雖然封裝構造函數的過程會比較麻煩,但一旦封裝成功,我們再創建對象就會變得非常輕松,這也是我們為什么要使用構造函數的原因。
在使用對象字面量創建一系列同一類型的對象時,這些對象可能具有一些相似的特征(屬性)和行為(方法),此時會產生很多重復的代碼,而使用構造函數就可以實現代碼的復用。
3.構造函數的執行過程先說一點基本概念。
function Animal(color) { this.color = color; }
當一個函數創建好以后,我們并不知道它是不是構造函數,即使像上面的例子一樣,函數名為大寫,我們也不能確定。只有當一個函數以 new 關鍵字來調用的時候,我們才能說它是一個構造函數。就像下面這樣:
var dog = new Animal("black");
以下我們只討論構造函數的執行過程,也就是以 new 關鍵字來調用的情況。
我們還是以上面的 Person 為例。
function Person(name, gender, hobby) { this.name = name; this.gender = gender; this.hobby = hobby; this.age = 6; } var p1 = new Person("zs", "男", "basketball");
此時,構造函數會有以下幾個執行過程:
(1) 當以 new 關鍵字調用時,會創建一個新的內存空間,標記為 Animal 的實例。
(2) 函數體內部的 this 指向該內存
通過以上兩步,我們就可以得出這樣的結論。
var p2 = new Person("ls", "女", "dancing"); // 創建一個新的內存 #f2 var p3 = new Person("ww", "女", "singing"); // 創建一個新的內存 #f3
每當創建一個實例的時候,就會創建一個新的內存空間(#f2, #f3),創建 #f2 的時候,函數體內部的 this 指向 #f2, 創建 #f3 的時候,函數體內部的 this 指向 #f3。
(3) 執行函數體內的代碼
通過上面的講解,你就可以知道,給 this 添加屬性,就相當于給實例添加屬性。
(4) 默認返回 this
由于函數體內部的 this 指向新創建的內存空間,默認返回 this ,就相當于默認返回了該內存空間,也就是上圖中的 #f1。此時,#f1的內存空間被變量 p1 所接受。也就是說 p1 這個變量,保存的內存地址就是 #f1,同時被標記為 Person 的實例。
以上就是構造函數的整個執行過程。
4.構造函數的返回值構造函數執行過程的最后一步是默認返回 this 。言外之意,構造函數的返回值還有其它情況。下面我們就來聊聊關于構造函數返回值的問題。
(1)沒有手動添加返回值,默認返回 this
function Person1() { this.name = "zhangsan"; } var p1 = new Person1();
按照上面講的,我們復習一遍。首先,當用 new 關鍵字調用時,產生一個新的內存空間 #f11,并標記為 Person1 的實例;接著,函數體內部的 this 指向該內存空間 #f11;執行函數體內部的代碼;由于函數體內部的 this 指向該內存空間,而該內存空間又被變量 p1 所接收,所以 p1 中就會有一個 name 屬性,屬性值為 "zhangsan"。
p1: { name: "zhangsan" }
(2) 手動添加一個基本數據類型的返回值,最終還是返回 this
function Person2() { this.age = 28; return 50; } var p2 = new Person2(); console.log(p2.age); // 28
p2: { age: 28 }
如果上面是一個普通函數的調用,那么返回值就是 50。
(3) 手動添加一個復雜數據類型(對象)的返回值,最終返回該對象
直接上例子
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"
再來一個例子
function Person4() { this.gender = "男"; return { gender: "中性" }; } var p4 = new Person4(); console.log(p4.gender); // "中性"
關于構造函數的返回值,無非就是以上幾種情況,大家可以動手試一試,也就記住了。
最后總結一下,本文從四個方面介紹了構造函數,而構造函數是原型和原型鏈學習的基礎,所以大家有必要花點時間好好學習一下關于構造函數的知識,下篇文章我會來講講人人都能看懂的原型鏈,敬請期待。
最后的最后,我所說的不一定都對,你一定要自己試試!
(本文完)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107659.html
摘要:上篇文章介紹了構造函數的部分實現,當前實例不是組件時,會執行方法。這個文件就是對構造函數進行的第一層包裝了。但是注意這里的代碼我們構造函數的第二層包裝,就在這個文件里了。回到的源碼中,當不存在時,直接返回基礎構造器的。 上篇文章介紹了Vue構造函數的部分實現,當前Vue實例不是組件時,會執行mergeOptions方法。 vm.$options = mergeOptions( re...
摘要:果然我們找到了的構造函數定義。告訴你是一個構造函數,需要用操作符去調用。在深入方法之前,我們先把目光移到文件里在的構造函數定義之后,有一系列方法會被立即調用。下篇博文主要介紹相關的內容,涉及到原型鏈和構造函數以及部分的實現,敬請期待 上篇博文中說到了Vue源碼的目錄結構是什么樣的,每個目錄的作用我們應該也有所了解。我們知道core/instance目錄主要是用來實例化Vue對象,所以我...
摘要:閱讀的源碼,或者說閱讀一個框架的源碼,了解它的目錄結構都是很有幫助的。人人都能懂的源碼系列文章將會詳細的介紹源碼的方方面面。 閱讀Vue的源碼,或者說閱讀一個框架的源碼,了解它的目錄結構都是很有幫助的。下面我們來看看Vue源碼的目錄結構。showImg(https://segmentfault.com/img/bV8fLS?w=598&h=654); Vue各目錄簡介 下圖是Vue各個...
摘要:上一篇文章中說道,函數要分兩種情況進行說明,第一種是為基礎構造器的情況,這個已經向大家介紹過了,今天這篇文章主要介紹第二種情況,是創建的子類。表示的是當前構造器上新增的,表示的是當前構造器上新增的封裝。 上一篇文章中說道,resolveConstructorOptions函數要分兩種情況進行說明,第一種是Ctor為基礎構造器的情況,這個已經向大家介紹過了,今天這篇文章主要介紹第二種情況...
摘要:上一篇文章中說道,函數要分兩種情況進行說明,第一種是為基礎構造器的情況,這個已經向大家介紹過了,今天這篇文章主要介紹第二種情況,是創建的子類。表示的是當前構造器上新增的,表示的是當前構造器上新增的封裝。 上一篇文章中說道,resolveConstructorOptions函數要分兩種情況進行說明,第一種是Ctor為基礎構造器的情況,這個已經向大家介紹過了,今天這篇文章主要介紹第二種情況...
閱讀 2088·2021-11-24 09:39
閱讀 1551·2021-10-11 10:59
閱讀 2499·2021-09-24 10:28
閱讀 3376·2021-09-08 09:45
閱讀 1269·2021-09-07 10:06
閱讀 1667·2019-08-30 15:53
閱讀 2061·2019-08-30 15:53
閱讀 1420·2019-08-30 15:53