JS常見構(gòu)造模式實(shí)例對(duì)比分析
本文實(shí)例分析了JS常見構(gòu)造模式。分享給大家供大家參考,具體如下:
1.工廠模式
沒有解決對(duì)象識(shí)別的問題。因?yàn)楹瘮?shù)內(nèi)部使用了new Object來創(chuàng)建對(duì)象
function Factory(name,age)
{
var o=new Object();
o.name=name;
o.age=age;
o.what=what;//用函數(shù)引用的方式消除重復(fù)創(chuàng)建相同函數(shù)的弊端,節(jié)省資源.函數(shù)引用可以修改this的指向,函數(shù)調(diào)用不可以!
return o;
}
what=funciton()
{
alert(this.name+this.age);
}
var o=Factory("12",12);
o.what();//what中的this指向o對(duì)象
這時(shí)候的constructor是Object,同時(shí)所有通過工廠模式返回的對(duì)象都是Object類型,所以instanceof操作符沒有意義
console.log(o.constructor);
//打印function Object() { [native code] }
console.log(o instanceof Object);
//而且這時(shí)候所有的對(duì)象都是Object類型的
2.構(gòu)造函數(shù)模式
function Person(name,age)
{
this.name=name;
this.age=age;
this.sayName=function(){ alert(this.name);}//相當(dāng)于this.sayName=new Function("alert(this.name)")
}
var p1=new Person("xx",12);
var p2=new Person("yy",13);
alert(p1.sayName==p2.sayName)//內(nèi)存地址不一樣!返回false
構(gòu)造函數(shù)相比工廠模式的優(yōu)點(diǎn)在于能夠正確的返回對(duì)象的類型,instanceof返回正確的結(jié)果。缺點(diǎn)在于如果向上面那樣,那么在每一個(gè)對(duì)象上面都要有一個(gè)sayName方法,而且這些sayName方法不是同一個(gè)Function實(shí)例,因?yàn)镋CMAScript中函數(shù)是對(duì)象,因此每定義一個(gè)函數(shù),也就是實(shí)例化了一個(gè)對(duì)象!
對(duì)上面的方法進(jìn)行優(yōu)化:
function Person(name,age)
{
this.name=name;
this.age=age;
this.sayName=sayName;//函數(shù)引用的方法,共享了同一個(gè)sayName,p1,p2的內(nèi)存地址一樣,p1.sayName==p2.sayName返回true
}
function sayName()
{
alert(this.name);
}
缺點(diǎn):全局函數(shù)sayName只能被某個(gè)對(duì)象調(diào)用p1.sayName,讓全局函數(shù)名不副實(shí);如果對(duì)象要定義很多方法,那么就要定義很多的全局函數(shù),所以自定義的引用類型沒有封裝性可言
3.原型模式
(1)無法通過構(gòu)造函數(shù)參數(shù)向原型屬性動(dòng)態(tài)傳值,后果就是:沒有個(gè)性,改變?cè)蛯傩缘闹?,所有的?shí)例都會(huì)受到干擾!
(2)當(dāng)原型屬性的是引用類型的時(shí)候,如果在一個(gè)對(duì)象實(shí)例上修改屬性,將會(huì)影響所有實(shí)例!
總之一句話:牽一發(fā)而動(dòng)全身(包括屬性和引用類型的值)是原型模式的特點(diǎn)。但是相比于構(gòu)造函數(shù)類型,原型類型滿足
person1.sayName===person2.sayName//兩者的引用是一樣的
4.構(gòu)造函數(shù)原型模式
用構(gòu)造函數(shù)定義個(gè)性,用原型模式定義共性
function Person(name,age)
{
this.name=name;
this.age=age;
this.friends=['liangklfang','qinliang'];
}
//用原型定義共性
Person.prototype={
constructor:Person,
sayName:function()
{
console.log(this.name);
}
}
var person1=new Person('liangklfang',"12");
var person2=new Person('liangklf',"14");
console.log(person1.sayName===person2.sayName);
//共性是函數(shù),打印true
console.log(person1.friends===person2.friends);
//friends是個(gè)性,打印false
也可以對(duì)構(gòu)造函數(shù)原型模式進(jìn)行優(yōu)化,就是常說的動(dòng)態(tài)原型模式
function Book(title,page)
{
this.title=title;
this.page=page;
if(typeof Book.isLock=="undefined")
//第一次的時(shí)候,Book.isLock是undefined,給原型綁定函數(shù),以后就不需要了,他相比于構(gòu)造函數(shù)原型模式的優(yōu)點(diǎn)在于把所有的邏輯全部封裝到構(gòu)造函數(shù)里面!
{
alert("Enter!");
Book.prototype.what=function()
{
alert(this.title+this.pages);
}
Book.isLock=true;
}
}
//下面的兩次調(diào)用alert("Enter!")只會(huì)調(diào)用因此i,因?yàn)榈谝淮我呀?jīng)通過Book.isLock設(shè)置為true了!相當(dāng)于靜態(tài)方法!;
var b1=new Book("me",12);
b1.what();
var b2=new Book("he",13);
b2.what();
也可以在this中直接檢測(cè),而不用給函數(shù)對(duì)象一個(gè)屬性
function Book(title,page)
{
this.title=title;
this.page=page;
if(typeof this.sayName!='function')
//第二次構(gòu)造對(duì)象的時(shí)候會(huì)在原型中查找到sayName!
{
Book.prototype.sayName=function()
{
console.log(this.title);
}
}
}
5.寄生構(gòu)造函數(shù)模式
除了使用new操作符以外,和工廠設(shè)計(jì)模式是一模一樣的!可以在特殊的情況下為對(duì)象創(chuàng)建構(gòu)造函數(shù),例如想用構(gòu)造函數(shù)方式創(chuàng)建一個(gè)具有額外方法的特殊數(shù)組,因?yàn)椴荒苤苯有薷腁rray的構(gòu)造函數(shù),因此可以用這個(gè)模式!
function SpecialArray()
{
var value=new Array();
value.push.apply(value,arguments);
value.toPipedString=function()
{
return this.join("|");
}
return value;
}
總之,寄生構(gòu)造函數(shù)的特點(diǎn)就是:有點(diǎn)像java中的裝飾模式!把原來的對(duì)象進(jìn)行裝飾,同時(shí)返回裝飾后的對(duì)象!這里就是把Array對(duì)象進(jìn)行了裝飾!添加了toPipe的String方法。缺點(diǎn)就是不能依賴instanceof操作符確定對(duì)象類型了,因?yàn)楹筒辉侔b類里面創(chuàng)建的對(duì)象是一模一樣的!
6. 穩(wěn)妥構(gòu)造函數(shù)模式
特點(diǎn):沒有公共屬性,而且其方法也不引用this的對(duì)象,instanceof失效。和寄生構(gòu)造函數(shù)的不同在于不使用new來構(gòu)造函數(shù),同時(shí)實(shí)例方法不引用this。實(shí)際是閉包
function Person(name,age,job)
{
var o=new Object();
o.sayName=funciton(){alert(name)}//這里實(shí)例方法沒有引用this,除了sayName不會(huì)有方法訪問傳入到構(gòu)造函數(shù)中的原始數(shù)據(jù)!
return o;
}
var friend=Person("xx",12,"teacher");
friend.name="female";//即使可以為這個(gè)對(duì)象修改了屬性name
friend.sayName();//不會(huì)被修改,依然彈出xx。不是female。但是,如果把上面的修改成:o.sayName=function(){alert(this.name)}//那么就會(huì)彈出female,也就是friend.name被修改成功了,如果沒有this,那么name的值一直引用的是原來的參數(shù)值!
感興趣的朋友還可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試運(yùn)行上述js代碼。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- JS面向?qū)ο蠡A(chǔ)講解(工廠模式、構(gòu)造函數(shù)模式、原型模式、混合模式、動(dòng)態(tài)原型模式)
- js面向?qū)ο笾R妱?chuàng)建對(duì)象的幾種方式(工廠模式、構(gòu)造函數(shù)模式、原型模式)
- JavaScript繼承基礎(chǔ)講解(原型鏈、借用構(gòu)造函數(shù)、混合模式、原型式繼承、寄生式繼承、寄生組合式繼承)
- 詳解JavaScript中的構(gòu)造器Constructor模式
- 構(gòu)造函數(shù)+原型模式構(gòu)造js自定義對(duì)象(最通用)
- javascript組合使用構(gòu)造函數(shù)模式和原型模式實(shí)例
- javascript設(shè)計(jì)模式之對(duì)象工廠函數(shù)與構(gòu)造函數(shù)詳解
- JavaScript構(gòu)造函數(shù)詳解
- JS特殊函數(shù)(Function()構(gòu)造函數(shù)、函數(shù)直接量)區(qū)別介紹
- 深入理解javascript構(gòu)造函數(shù)和原型對(duì)象
- JavaScript中的普通函數(shù)與構(gòu)造函數(shù)比較
相關(guān)文章
使用原生js+canvas實(shí)現(xiàn)模擬心電圖的實(shí)例
下面小編就為大家?guī)硪黄褂迷鷍s+canvas實(shí)現(xiàn)模擬心電圖的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
safari,opera嵌入iframe頁面cookie讀取問題解決方法
最近做的合作網(wǎng)站嵌入到對(duì)方的iframe中去,在safari,opera和有些版本的搜狗瀏覽器(內(nèi)核版本原因)中不能讀到cookie。2010-06-06
JavaScript?中如何攔截全局?Fetch?API?的請(qǐng)求和響應(yīng)問題
在本文中,我們介紹了什么是 JavaScript 攔截器,學(xué)習(xí)了如何通過給 Fetch API 使用猴子補(bǔ)丁和使用 fetch-intercept 庫(kù)來創(chuàng)建攔截器,對(duì)js攔截全局Fetch?API的請(qǐng)求和響應(yīng)知識(shí)感興趣的朋友跟隨小編一起看看吧2023-01-01
前端js?sm2實(shí)現(xiàn)加密簡(jiǎn)單代碼舉例
在Vue項(xiàng)目中實(shí)現(xiàn)數(shù)據(jù)加密,首先需要安裝SM2加密庫(kù),如js-sm2或sm-crypto,通過npm或yarn進(jìn)行安裝后,在Vue組件或文件中引入該庫(kù),并使用其提供的加密、解密功能,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09
JavaScript數(shù)組分組groupBy示例詳解
JavaScript?最近發(fā)布了一個(gè)方法?Object.groupBy,可以對(duì)可迭代對(duì)象中的元素進(jìn)行分組,這篇文章主要介紹了JavaScript數(shù)組分組groupBy示例,需要的朋友可以參考下2023-12-12
讓FireFox支持innerText的實(shí)現(xiàn)代碼
DHTML非標(biāo)準(zhǔn)屬性innerText在FireFox中的使用2009-12-12
JavaScript算法教程之sku(庫(kù)存量單位)詳解
這篇文章主要給大家介紹了JavaScript算法教程之sku(庫(kù)存量單位)的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-06-06
JavaScript使用math.js進(jìn)行精確計(jì)算操作示例
這篇文章主要介紹了JavaScript使用math.js進(jìn)行精確計(jì)算操作,結(jié)合實(shí)例形式分析了開源庫(kù)math.js進(jìn)行高精度數(shù)學(xué)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2018-06-06

