Javascript創建對象的幾種方式?

javascript 中常見的創建對象的幾種方式:

?1.?使用Object構造函數創建;

使用Object構造函數來創建一個對象,下面代碼創建了一個person對象,并用兩種方式打印出了Name的屬性值。

var person = new Object();
person.name="kevin";
person.age=31;
alert(person.name);
alert(person["name"])

2. 使用對象字面量創建一個對象;

var person ={name:"Kevin",age:31,5:"Test"
};
alert(person.name);
alert(person["5"]);

3. 使用工廠模式創建對象;

返回帶有屬性和方法的person對象。

function createPerson(name, age,job){var o = new Object();o.name=name;o.age=31;o.sayName=function(){alert(this.name);};return o;
}
createPerson("kevin",31,"se").sayName();

用函數來封裝以特定接口創建對象的細節,解決了創建多個相似對象的問題,但是沒有解決對象識別的問題(怎么知道一個對象的類型)。

4. 使用自定義構造函數模式創建對象;

這里注意命名規范,作為構造函數的函數首字母要大寫,以區別其它函數。這種方式有個缺陷是sayName這個方法,它的每個實例都是指向不同的函數實例,而不是同一個。構造函數模式,構造函數添加屬性和方法,使用的時候new一個自定義的對象

function Person(name,age,job)
{this.name=name;this.age=age;this.job=job;this.sayName=function(){alert(this.name);};
}var person = new Person("kevin",31,"SE");
person.sayName();

new一個構造函數的內部操作步驟:

1)、創建一個新對象;

2)、將構造函數的作用域賦給新對象(因此this就指向了這個新對象);

3)、執行構造函數中的代碼;

4)、返回新對象。

使用構造函數創建的實例,都會有一個constructor屬性,指向構造函數。

創建自定義的構造函數意味著將來可以將它的實例標識為一種特定的類型。這正是勝過工廠模式的地方。

與普通函數的區別在于new調用,不用new來調用,與普通函數無差。

不使用new調用的時候,就相當于window調用了構造函數,屬性和方法都被添加到了window對象上去。

也可以這樣使用:(call就是為了改變上下文環境而生)

var o = new Object();
Person.call(o,"Dadaoshenyi",25,"Enginner");
o.sayName();//"Dadaoshenyi"

構造函數創建對象的問題:每個方法都要在實例上重寫一遍。由于函數也是對象,因此每次定義一個函數,也就實例化了一個對象。

5. 使用原型模式創建對象;

解決了方法4中提到的缺陷,使不同的對象的函數(如sayFriends)指向了同一個函數。

但它本身也有缺陷,就是實例共享了引用類型friends,從下面的代碼執行結果可以看到,兩個實例的friends的值是一樣的,這可能不是我們所期望的。原型模式,定義構造函數,構造函數原型上添加屬性和方法。?

function Person(){}Person.prototype = {constructor : Person,name:"kevin",age:31,job:"SE",friends:["Jams","Martin"],sayFriends:function(){alert(this.friends);}
};
var person1 = new Person();
person1.friends.push("Joe");
person1.sayFriends();//Jams,Martin,Joe
var person2 = new Person(); 
person2.sayFriends();//James,Martin,Joe

構造函數的原型||對象實例的內部指針([[Prototype(__proto__)]]指向Person.prototype)。

實例對象的內部指針指向構造函數的原型。

原型模式的優點:自定義的構造函數,可以讓所有的對象實例共享原型對象所包含的屬性和方法。原生的引用類型也是采用這種模式。

問題在于:1、省略了構造函數傳遞參數的步驟。2、所有實例共享方法和屬性,這樣,實例修改原來的屬性或者方法,將會在所有的實例上表現出來。被捆綁到了一起。只是一個引用,不是一個副本。

6. 組合使用原型模式和構造函數創建對象;

解決了方法5中提到的缺陷,而且這也是使用最廣泛、認同度最高的創建對象的方法。組合使用構造函數模式和原型模式,最常用的一種模式。?

function Person(name,age,job)
{this.name=name;this.age=age;this.job=job;
this.friends=["Jams","Martin"]; } Person.prototype.sayFriends=function() {alert(this.friends); };
// Person.prototype = {
// constructor: Person,
// sayFriends: function() {
// alert(this.friends);
// }
// };
var person1 = new Person("kevin",31,"SE");
var person2 = new Person("Tom",30,"SE");
person1.friends.push("Joe");
person1.sayFriends();//Jams,Martin,Joe
person2.sayFriends();//Jams,Martin

優點:使用構造函數來創建實例屬性,且可以修改設定的值。使用原型創建共享方法和共享的屬性。最大限度的節省了內存。

7. 動態原型模式;

這個模式的好處在于看起來更像傳統的面向對象編程,具有更好的封裝性,因為在構造函數里完成了對原型創建。這也是一個推薦的創建對象的方法。動態原型模式,將上面的對象原型方法||屬性的創建方法哦了構造函數里面完成。具有更好的封裝性。結果是一樣的。?

function Person(name,age,job)
{//屬性this.name=name;this.age=age;this.job=job;this.friends=["Jams","Martin"];//方法if(typeof this.sayName != "function"){Person.prototype.sayName=function(){alert(this.name);};Person.prototype.sayFriends=function(){alert(this.friends);};}
}var person = new Person("kevin",31,"SE");
person.sayName();
person.sayFriends();

另外還有兩個創建對象的方法,寄生構造函數模式和穩妥構造函數模式。由于這兩個函數不是特別常用,這里就不給出具體代碼了。

寫了這么多創建對象的方法,其實真正推薦用的也就是方法6和方法7。當然在真正開發中要根據實際需要進行選擇,也許創建的對象根本不需要方法,也就沒必要一定要選擇它們了。

?

轉載于:https://www.cnblogs.com/changyangzhe/p/5721968.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260930.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260930.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260930.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用DIV之后 table何去何從

表格并非雞肋 相反是一道大餐 XHTML標準中的一些元素分為三大類: 輔助布局設計元素:DIV SPAN 這類元素的主要功能是用來布局整個頁面的,靈活使用這些元素的各種屬性,可以讓你的頁面表現豐富多彩。結構化元素或信息元素&#xff1…

使用 RMAN 同步數據庫

使用 RMAN 同步數據庫使用 RMAN 同步數據庫一.概述二 操作步驟(一).把生產庫置為歸檔模式(二).啟動rman做數據庫0級備份(三).修改生產庫數據庫到未歸檔(四).拷貝備份集到測試庫(五).在測試庫上的操作一.概述 因項目組遇…

解決 用戶'sa'登錄失敗。錯誤:18456 問題

問題描述:用戶sa登錄失敗。錯誤:18456 產生原因:由于服務器身份驗證模式為‘Windows 身份驗證模式’,所以導致登錄失敗 解決方案: 1.使用‘Windows 身份驗證模式’登錄服務器 2.打開‘對象資源管理器’,右鍵根節點…

js實現圖片上傳預覽及進度條

js實現圖片上傳預覽及進度條 原文js實現圖片上傳預覽及進度條 最近在做圖片上傳的時候&#xff0c;由于產品設計的比較fashion&#xff0c;上網找了比較久還沒有現成的&#xff0c;因此自己做了一個&#xff0c;實現的功能如下&#xff1a; 1&#xff1a;去除瀏覽器<input …

webapi文檔描述-swagger

最近做的項目使用mvcwebapi&#xff0c;采取前后端分離的方式&#xff0c;后臺提供API接口給前端開發人員。這個過程中遇到一個問題后臺開發人員怎么提供接口說明文檔給前端開發人員,最初打算使用word文檔方式進行交流&#xff0c;實際操作中卻很少動手去寫。為了解決這個問題&…

《推薦系統實踐》樣章:如何利用用戶標簽數據

《推薦系統實踐》樣章&#xff1a;如何利用用戶標簽數據 推薦系統的目的是聯系用戶的興趣和物品&#xff0c;這種聯系需要依賴于不同的媒介。GroupLens在文章1中認為目前流行的推薦系統基本上通過三種方式來聯系用戶興趣和物品。如圖1所示&#xff0c;第一種方式是通過用戶喜歡…

應用程序創建自己的奔潰轉儲(crash dump)文件

1、注冊自定義的UnhandledExceptionFilter&#xff0c;C/C Runtime Library下需要注意自定義handler被移除&#xff08;hook kernel32.dll的SetUnhandledExceptionFilter使它返回一個空指針即可&#xff09;。 PTOP_LEVEL_EXCEPTION_FILTER v_prevUnhandledExceptionFilter;…

jqMobi + Android 試手

忙活的一個晚上&#xff0c;搞定了一個界面&#xff0c;主要在滾動條和風格上花了不少時間&#xff0c;jqMobi的文檔真的少的可憐&#xff0c;希望文檔可以多點&#xff0c;以下是幾份參考資料&#xff1a; 最新的Api參考&#xff1a;http://www.shareach.com/jq/一些簡單的范例…

STM32 基于正電原子開發板,改換芯片為STM32F103R6,Proteus仿真的一些問題

最近在學STM32&#xff0c;網上收集了一些信息&#xff0c;最后用正點原子的開發板來學習。 MDK的配置請參考原子哥的資料&#xff0c;我主要的學習方法是參考原子哥的開發板與實驗案例&#xff0c;改換不一樣的芯片&#xff0c;也要做出的一樣的效果。但在最基礎的入門就遇到…

深入理解閉包系列第二篇——從執行環境角度看閉包

前面的話 本文從執行環境的角度來分析閉包&#xff0c;先用一張圖開宗明義&#xff0c;然后根據圖示內容對代碼進行逐行說明&#xff0c;試圖對閉包進行更直觀的解釋 圖示 說明 下面按照代碼執行流的順序對該圖示進行詳細說明 function foo(){var a 2;function bar(){console.…

沒事寫著玩 系列之 JQ連連看(很丑陋,很初級)

說明:(圖片自備, 名稱為 jpg[0,2].jpg class為( one two three)對應 前面的 0,1,2) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://ww…

VS2017 調用Tesseract

最近在學tesseract&#xff0c;但遇到太多的問題是。 雖然網上有不少的方法&#xff0c;就算是按照tersseract&#xff0c;github上提供的方法也是編譯不成功。 問題一大堆。不過我也想到了其它方法最張還是可以用了。 我有2個方法&#xff0c; 方法1, 1&#xff0c;先build t…

最少步數----深搜

最少步數 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;4描述這有一個迷宮&#xff0c;有0~8行和0~8列&#xff1a; 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 1,0,0,1,1,0,0,0,1 1,0,1,0,1,1,0,1,1 1,0,0,0,0,1,0,0,1 1,1,0,1,0,1,0,0,1 1,1,0,1…

由單例模式造成的內存泄漏

使用單例模式時&#xff0c;有時候不小心&#xff0c;就會很容易造成內容泄漏&#xff0c;如下代碼所示&#xff1a;public class SingleInstance { private static volatile SingleInstance instance; private Context context; private SingleInstance(Context context) {thi…

在windows上安裝OpenCV

在windows上安裝OpenCV&#xff0c;官方提供的教程&#xff0c;我翻譯了一下。如有不正解&#xff0c;請指正 使用git-bash&#xff08;版本> 2.14.1&#xff09;和cmake&#xff08;版本> 3.9.1&#xff09;安裝 1.您必須下載cmake&#xff08;版本> 3.9.1&…

CFile、CStdioFile、FILE和其他文件操作(轉)

CFile //創建/打開文件 CFile file; file.Open(_T("test.txt"),CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite);//文件打開模式可組合使用&#xff0c;用“|”隔開&#xff0c;常用的有以下幾種&#xff1a; //CFile::modeCreate&#xff1a;以新建…

Oracle修改redo log大小的方法

目的:修改當前在線日志從默認50M增加至512M。1.查看當前日志組的狀態SQL> select group#,members,bytes/1024/1024,status from v$log;GROUP# MEMBERS BYTES/1024/1024 STATUS---------- ---------- --------------- ----------------1 1 50 INACT…

算法競賽入門經典 第一章 上機練習(C++代碼)

//平均數&#xff08;average&#xff09; //輸入3個整數&#xff0c;輸出它們的平均值&#xff0c;保留3位小數。 #include<iostream> #include<iomanip> using namespace std; int main() { int a,b,c; cin>>a>>b>>c; double average(abc)/3; …

CMake 編譯 OpenCV 項目,不是編譯OpenCV, 用了之后才知道CMake也太好用了。

新建一個 CMakeList.txt 復制下面代碼&#xff0c;并保存 cmake_minimum_required (VERSION 3.0)PROJECT(Chapter2)set (CMAKE_CXX_STANDARD 11)IF(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)conan_basic_setup() E…

Java Ajax jsonp 跨域請求

2019獨角獸企業重金招聘Python工程師標準>>> 1. 什么是JSONP 一般來說位于 server1.example.com 的網頁無法與不是 server1.example.com的服務器溝通&#xff0c;而 HTML 的<script> 元素是一個例外。利用 <script> 元素的這個開放策略&#xff0c;網頁…