當前位置:
首頁 > 最新 > JavaScript 起步:「new」 運算符-Hacker Noon

JavaScript 起步:「new」 運算符-Hacker Noon

你好!如果你剛來,這是我每周系列,JavaScript 起步的第4期。我推薦你在閱讀本文之前,先閱讀本系列的其它文章。

四項原則

理解 new 運算符最簡單的辦法就是搞明白它是幹什麼的。當你使用 new 的時候,會發生4件事情:

它創建一個新的空對象。

將 this 綁定到新創建的對象上。

在新創建的對象上添加一個叫「proto」 的屬性,這個屬性指向構造函數的原型(prototype)對象。

在函數結束前添加return this,這樣剛創建的對象可以從這這個函數返回出去。

等等,什麼?

如果不能完全理解這些規則也沒關係。我們從簡單的開始。創建一個叫 Student 的構造函數。這個函數有兩個參數,name 和 age。然後會將這兩個參數的值設置給 this 的屬性。

function Student(name, age) { this.name = name; this.age = age; }

不過現在用 new 調用我們的構造函數。我會傳入兩個參數: John 和 26。

var first = **new** Student( John , 26);

那麼運行上面的代碼會發生什麼事情?

創建了一個新對象 —— first 對象

this 綁定到 first 對象。所有 this 引用指向 first。

添加proto。first.proto現在指向 Studnet.prototype。

所有事情完成後,我們將新的 first 對象返回出來賦值給新的 first 變數。

現在我們來運行一個簡單的 console.log 語句測試代碼是否可運行:

console.log(first.name); // John console.log(first.age); // 26

非常棒。現在我們深入 new 關鍵字的proto部分。

原型每個 JavaScript 對象都有原型。JavaScript 的所有對象都從它們的原型繼承方法和屬性。

來看一個示例。打開你的 Chrome 開發者工具 控制台(Windows:Ctrl+Shift+J)(Mac: Cmd+Option+J),然後輸入本文前面定義的 Students 函數。

為了證明每個對象都有原型,我們現在輸入:

Student.prototype; // Object {...}

酷,返回了一個對象。現在嘗試創建一個新的學生對象:

var second = new Student( Jeff , 50);

我們已經使用了 Studnet 構造函數來創建第二個名為 Jeff 的學生。而且,因為我們使用 new 運算符,proto屬性應該已經添加到了我人的 second 對象中。它會指向父構造器。來看一下它們是否相等:

second.__proto__ === Student.prototype; // trueStudent.prototype.constructor; // function Student(name, age) { // this.name = name; // this.age = age; // }

這很快就得複雜起來。讓我們看看下面的簡圖,看能否讓你直觀地了解到這個過程:

很漂亮,不是嗎?

正如你在上面看到的,我們的 Student 構造函數 (其它構造函數也是一樣)有一個叫 .prototype 的屬性。這個原型上有一個對象叫 .constrcutor,往回指向構造函數。這是一個漂亮的小迴環。然後,在我們使用 new 運算符創建新對象的時候,每個對象都有 .proto屬性將新對象與 Student.prototype 連接起來。

為什麼這很重要?

因為繼承,它非常重要。原型對象由對應構造函數創建的所有對象共享。也就是說我們可以在原型中添加函數和屬性,而所有對象都可以使用。

在我們上面的示例中,我們只創建了兩個 Student 對象,但是如果不是 2 個學生,而是 20,000 個呢?我們在原型上定義函數而不是在每個學生對象上定義這種做法一下子就節省了大量的處理能力。

讓我們來看一個回到理想之家的例子。在控制台輸入下面的代碼:

再次說明,這裡所做的事情是為 Student 原型增加一個函數——現在任何我們創建的學生對象可以訪問這個新的 .sayInfo 函數!來測試一下:

second.sayInfo(); // Jeff is 50 years old

添加一個新的學生然後再次測試:

var third = new Student( Tracy , 15); // Now if we log third out, we see the object only has two // properties, age and name. Yet, we still have access to the // sayInfo function: third; // Student third.sayInfo(); // Tracy is 15 years old

有效果!有效果是因為……JavaScript 對象會首先查找是否有我們調用的屬性。如果沒有,它會向上查找,來到原型這裡,然後說「嗨,你有這個屬性嗎?」這種模式一直持續到我們找到屬性,或者達到原型鏈的終點。

因為相同的原因你可以通過繼承使用像 .toString() 這樣已經定義的方法!正因如此,既然你從來沒有寫過 toString() 方法,也可以好好的使用它。因為這個方法和其它內建的 JS 方法一樣,定義在 Object 的原型上。我們創建的每個對象最終都會找到 Object 原型上去。當然,我們可以重寫這些方法:

var name = { toString: function(){ console.log( Not a good idea ); } }; name.toString(); // Not a good idea

我們的對象首先檢查自己是否有需要的方法,然後才會到原型中去找。既然我們已經定義了這個方法,那直接運行就好,不需要使用繼承的方法了。但這並不是個好主意。最好保留全局方法,為你自己的方法換個別的名稱。

小結

作為新入行的開發者,可能很難理解這些概念,不過一旦理解了,就能寫出更好更有效的代碼。通過原型我們可以快速而有效地在成百上千個對象中共享相同的代碼。和我其它所有文章一樣,這篇文章是讓你了解一些基礎知識,然後你可以自己繼續深入學習。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 推酷 的精彩文章:

用三角形網格構建三維圖形
移動應用廣告之商業變現的實現策略
一個神經科學工作者眼中的Alexnet
Linux下logrotate 日誌輪詢操作梳理
漫山遍野的多邊形元素,正在入侵每一份設計稿

TAG:推酷 |

您可能感興趣

類型轉換運算符 運算符重載 operator new operator delete
Tensorflow_01_運算符與張量值
Linux shell 邏輯運算符、邏輯表達式詳解
SQLite AND/OR 運算符
Perl 運算符
python基礎之變數與運算符
Kotlin技術分享-運算符重載
shell編程-一些簡單的運算符
Lua 運算符
Python數據類型、運算符、變數
Python入門基礎之面向對象四:運算符重載
Python筆試現場編程:用位運算符實現加法,不允許使用 「+」
Python入門教程——邏輯運算符、身份運算符和成員運算符
C++友元重載+運算符易錯點
運算符,鍵盤錄入,流程式控制制語句if總結
無尾熊cp沒有涼?吳昕新節目公開擇偶標準,潘瑋柏還算符合!
新知 | 四則運算符的來源
四則運算符的來源
專家:中俄推行本幣結算符合兩國各自戰略需要
長壽的人,大多有幾個特點,就算符合一個,也是要恭喜的