摘要:中創建對象的方式有很多,尤其是基于原型的方式創建對象,是理解基于原型繼承的基礎。該函數中的屬性指向該源性對象當通過該函數的構造函數創建一個具體對象時,在這個對象中,就會有一個屬性指向原型。
js中創建對象的方式有很多,尤其是基于原型的方式創建對象,是理解基于原型繼承的基礎。因此在這里匯總一下,并對各種方法的利弊進行總結和對比,不至于以后對這些概念有模糊。
簡單方式創建var o = new Object();
我們都知道,實際上在javascript中并沒有所謂的類的概念。因此在創建對象時不能像面向對象語言那樣,通過類A new出來一個a對象。但是javascript有一個特殊的Object。我們可以借助Object來new一個對象。
然后可以通過如下方式給對象增加屬性或方法:
o.name="abc";
但是因為沒有類的約束,這種方式創建出來的對象無法實現對象的重復利用,并且沒有一種固定的約數,操作起來可能會出現這樣或者那樣的意想不到的問題。
有這樣一個例子:
var a = new Object; var b = new Object; var c = new Object; c[a]=a; c[b]=b; alert(c[a]===a); //輸出什么
關于這個例子的具體解答詳見 例子出處
工廠方法創建直接看一個例子:
function createPerson(){ var o = new Object(); o.name = "abc"; o.age = 20; return o; }
這種創建對象的方法是在一個function中new Object(),并且賦予屬性和方法,最后return 帶有這些屬性和方法的對象。
但是當我們想通過
var p1 = createPerson(); alert(typeof(p1));//Object 僅能得到這個結果,實際上沒有太大意義 alert(p1 instanceof(類名???))//會發現其實并不存在一個Person類構造函數的方式
function Person(name,age){ this.name = name; this.age = age; this.say = function(){ // } } var p1 = new Person("abc",20);
構造函數的方式創建的對象:
函數名即為類名
通過this來定義屬性
通過new Person()創建對象
并且有如下屬性:
alert(typeof(p1));// Person alert(p1 instanceof(Person));// true
但是同時我們也發現這種方式創建對象的一個弊端。對于類中的say方法,每分配一個對象就會有一個say的內存空間被分配出來。有一個say的拷貝。如果方法特別多的時候,會造成內存空間的極大浪費。可以通過兩種方式進行優化和改進:
將say聲明為全局的
function say(){ }
然后在類的定義中通過:
this.say = say;
采用下面提到的基于原型的方式創建對象
讓類中的行為統一指向全局的say方法。但是如果將所有的方法設為全局的時候,就可以被window對象調用,那么就破壞了對象的封裝性;如果方法很多,會造成代碼中充斥著大量的全局函數。
基于原型創建對象function Person(){ } Person.prototype.name = "abc"; Person.prototype.age= 20; Person.prototype.say= function(){ alert(this.name+this.age); } var p1 = new Person(); p1.say();//ok say();//no 完成了封裝
原型是js中的一個特殊對象。當一個函數創建之后,會隨之產生一個原型對象。該函數中的prototype屬性指向該源性對象;
當通過該函數的構造函數創建一個具體對象時,在這個對象中,就會有一個_prop_屬性指向原型。這些是js中的很重要的一種繼承方式--基于原型的繼承的基礎。這里不再贅述。
基于原型創建對象時,如果對象的屬性和方法特別多時,可以通過如下方式進行定義:
Person.prototype = { name:"abc", age:20, say:function(){ } }
稱為原型重寫。原型重寫之后當我們再通過 var p1 = new Person()創建一個對象時,p1 的constructor != Person()了。由于原型重寫了,而且沒有通過prototype指向,從而指向了Object()。
如果constructor比較重要,可以再json格式的定義中手動制定
constructor:Pserson
關于原型重寫,我畫了個示意圖,比較容易理解:
p1是原型重寫前聲明的對象,p2是原型重寫
Person.prototype.name = "123";
之后的聲明的對象。
可以看出
constructor的指向確實沒有自動變換,除非通過上述手動的方式進行修改。
通過p2.name = "456",設置name時,會在自己的存儲空間中存儲。當然查找name屬性時,也是從自己的內存空間中讀取name值。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/85977.html
摘要:模式,單實例多進程,常用于多語言混編,比如等,不支持端口復用,需要自己做應用的端口分配和負載均衡的子進程業務代碼。就是我們需要一個調度者,保證所有后端服務器都將性能充分發揮,從而保持服務器集群的整體性能最優,這就是負載均衡。 showImg(https://segmentfault.com/img/remote/1460000019425391?w=1440&h=1080); Nod...
摘要:模式,單實例多進程,常用于多語言混編,比如等,不支持端口復用,需要自己做應用的端口分配和負載均衡的子進程業務代碼。就是我們需要一個調度者,保證所有后端服務器都將性能充分發揮,從而保持服務器集群的整體性能最優,這就是負載均衡。 showImg(https://segmentfault.com/img/remote/1460000019425391?w=1440&h=1080); Nod...
摘要:模式,單實例多進程,常用于多語言混編,比如等,不支持端口復用,需要自己做應用的端口分配和負載均衡的子進程業務代碼。就是我們需要一個調度者,保證所有后端服務器都將性能充分發揮,從而保持服務器集群的整體性能最優,這就是負載均衡。 showImg(https://segmentfault.com/img/remote/1460000019425391?w=1440&h=1080); Nod...
摘要:采用了新舊的對比,獲取差異的,最后一次性的更新到真實上。對基本屬性進行監聽對對象進行監聽對對象某一個屬性監聽監聽自定義指令全局指令,第一個參數是指令名,第二個參數是一個對象,對象內部有個的函數,函數里有這個參數,表示綁定了這個指令的元素。 11.vue 虛擬DOM的理解 Web界面由DOM樹(樹的意思是數據結構)來構建,當其中一部分發生變化時,其實就是對應某個DOM節點發生了變化,??...
閱讀 2978·2023-04-26 02:04
閱讀 1286·2021-11-04 16:07
閱讀 3712·2021-09-22 15:09
閱讀 684·2019-08-30 15:54
閱讀 1906·2019-08-29 14:11
閱讀 2533·2019-08-26 12:19
閱讀 2261·2019-08-26 12:00
閱讀 763·2019-08-26 10:27