【20190220】JavaScript-知識點理解:對象創建方式、原型、閉包

来源:https://www.cnblogs.com/huangrui-dori/archive/2019/02/20/10405757.html
-Advertisement-
Play Games

一、對象創建方式 1. 工廠模式 這種模式抽象了創建具體對象的過程,用函數來封裝以特定介面創建對象的細節。存在的問題是無法通過 instanceof 識別一個對象的類型。 2. 構造函數模式 創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。利用構造函數模式創建實例對象時,必須使用new操作 ...


一、對象創建方式

1. 工廠模式

這種模式抽象了創建具體對象的過程,用函數來封裝以特定介面創建對象的細節。存在的問題是無法通過 instanceof 識別一個對象的類型。

 1 function createPerson(name,age,job){
 2     var o=new object();
 3     o.name=name;
 4     o.age=age;
 5     o.job=job;
 6     o.sayName=function(){
 7         alert(this.name);
 8     }
 9     return o;
10 }
11 
12 var person=createPerson("Greg","27","Doctor");

 

2. 構造函數模式

創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。利用構造函數模式創建實例對象時,必須使用new操作符,並可以通過 instanceof 檢測到對象的自定義類型。

 1 function Person(name,age,job){
 2     this.name=name;
 3     this.age=age;
 4     this.job=job;
 5     this.sayName=function(){
 6         alert(this.name);
 7     }
 8 }
 9 
10 var person=new Person("Greg","27","Doctor");//1.創建一個新對象;2.將構造函數的作用域賦給新對象(this指向新對象);3.執行構造函數中的代碼;4.返回新對象

此時存在的問題是自定義對象中定義的方法都要在每個實例上重新創建一遍,也就是說不同實例上的同名函數是不相等的。雖然可以通過將函數定義轉移到構造函數外來解決,這時每個實例中的函數引用的都是在全局作用域中定義的一個全局函數。但是這又帶來了新的問題,就是當對象需要定義很多方法時,就需要定義很多個全局函數。

 

3. 原型模式

我們創建的每個函數都有一個prototype(原型)屬性,它是一個指針,指向一個對象,即原型對象,原型對象可以讓所有對象實例共用它所包含的屬性和方法。存在的問題是所有實例在預設情況下都將取得相同的屬性值。

 1 function Person(){
 2 }
 3 
 4 Person.prototype={
 5     constructor:Person,//這裡實際上是重寫了Person的原型對象,因此其constructor指向的是Object構造函數,此時通過instanceof能識別到特定類型,但其constructor已經無法確定對象類型了,因此可以重新將它設置回適當的值。
 6     name:"Nicholas",
 7     age:29,
 8     job:"Doctor",
 9     sayName:function(){
10         alert(this.name);
11     }
12 };
13 
14 var person=new Person();

 

4. 組合使用構造函數模式和原型模式

這是創建自定義類型的最常見方法,構造函數模式用於定義實例屬性,原型模式用於定義方法和共用的屬性。

 1 function Person(name,age,job){
 2     this.name=name;
 3     this.age=age;
 4     this.job=job;
 5     this.friends=["Shelby","Court"];
 6 }
 7 
 8 Person.prototype={
 9     constructor:Person,
10     sayName:function(){
11         alert(this.name);
12     }
13 }
14 
15 var person=new Person("Greg",27,"Doctor");

 

5. 動態原型模式

把所有信息都封裝在構造函數中,通過在構造函數中初始化原型,保持了同時使用構造函數和原型的優點。也就是說可以通過檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。這時不能用對象字面量重寫原型,如果在以及創建了實例的情況下重寫原型,會切斷現有實例與新原型之間的聯繫。

 1 function Person(name,age,job){
 2     this.name=name;
 3     this.age=age;
 4     this.job=job;
 5 
 6     if(typeof this.sayName != "function"){
 7         Person.prototype.sayName=function(){
 8             alert(this.name);
 9         }
10     }
11 }
12 
13 var person=new Person("Greg","27","Doctor");

 

6. 寄生構造函數模式

這種模式除了使用new操作符創建實例對象並把使用的包裝函數稱作構造函數之外,與工廠模式是一樣的。這個模式可以在特殊情況下用來為對象創建構造函數,如想創建一個具有額外方法的特殊數組。但需要註意的是返回的對象與構造函數以及構造函數的原型屬性之間沒有關係,因此不能通過instanceof識別對象類型。建議在可以使用其他模式的情況下不要使用這種模式。

 

7. 穩妥構造函數模式

穩妥對象指的是沒有公共屬性,而且其方法也不引用this的對象,它適合在一些安全的環境中(這些環境中會禁止使用this和new),或者在防止數據被其他應用程式改動時使用。穩妥構造函數與寄生構造函數有類似的模式,但有兩點不同:一是新創建對象的實例方法不引用this;二是不使用new操作符調用構造函數。

 

二、閉包

閉包是指有權訪問另一個函數作用域中的變數的函數,創建閉包的常見方式就是在一個函數內部創建另一個函數,應用的兩種情況是:一是函數作為返回值;二是函數作為參數傳遞。

由於在另一個函數內部定義的函數會將外部函數的活動對象添加到它的作用域鏈中,因此即使當外部函數返回後,其執行環境的作用域鏈會被銷毀,但它的活動對象仍然留在記憶體中,因為在其內部定義的函數仍然在引用它。

直到內部函數被銷毀後,外部函數的活動對象才會被銷毀。所以使用閉包會增加記憶體開銷。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先按照mint-ui的文檔中按需引入的要求,先執行 然後,將.babelrc文件替換了,但是後來我又將其改了(採坑過程我也改來改去),下麵附圖: 接著運行,報錯: 說是沒有安裝es2015,然後安裝cnpm install babel-preset-es2015 --save-dev 然後運行: ...
  • 什麼是AJAX? AJAX = Asynchronous JavaScript and XML(非同步的 JavaScript 和 XML)。 AJAX 不是新的編程語言,而是一種使用現有標準的新方法。 AJAX 最大的優點是在不重新載入整個頁面的情況下,可以與伺服器交換數據並更新部分網頁內容。 AJ ...
  • 一、CSS簡單規則 CSS樣式表包含3部分內容:選擇符、屬性和屬性值 其中選擇符包括基本的3種選擇器: 1、標記選擇器,如<a></a>標簽等; 2、類別選擇器,用class屬性來聲明即可; 3、id選擇器,用id來聲明,只能使用1次。 二、CSS選擇器 1、標記選擇器,例如對<a></a>標簽,下 ...
  • 當不給父元素設置寬高時,父元素的寬高會被子元素的內容撐開。但是當子元素設置浮動屬性後,子元素會溢出到父元素外,父元素的寬高也不會被撐開了,稱之為“高度塌陷”。 解決辦法: 1.給父元素設置 overflow 添加 overflow 不僅減少了代碼量,還不存在語義化的問題,但是也可能因為內容增加導致超 ...
  • js監聽瀏覽器tab視窗切換 ——IT唐伯虎 摘要:js監聽瀏覽器tab視窗切換。 if (document.hidden !== undefined) { document.addEventListener('visibilitychange', () => { console.debug(doc ...
  • 跨域報錯的原因 最開始上傳視頻成功後,video標簽的src會直接引入上傳後的服務端資源地址,然後使用canvas截圖就發生了跨域報錯的提示。 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not ...
  • transform是一些效果的集合,主要是移動、旋轉、縮放和傾斜這四種基本操作,還可以通過設置matrix矩陣來實現更複雜的效果。 變形transform可以實現2D和3D兩種效果。 變形transform本來是一個用來處理移動、旋轉、縮放和傾斜等基本操作的CSS3屬性,但該屬性除了完成其本職工作之 ...
  • [TOC] JavaScript的 對象模型 非常強大,但它與標準面向對象語言的對象模型稍有不同。JavaScript採用的不是基於類的面向對象系統,而是更強大的 原型 模型,其中的對象可繼承和擴展其他對象的行為。 JavaScript沒有傳統的面向對象模型,即從類創建對象的模型。事實上,JavaS ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...