欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中創(chuàng)建對(duì)象的模式匯總

 更新時(shí)間:2016年04月19日 10:36:03   作者:Merryhyl  
本文給大家js創(chuàng)建對(duì)象的模式包括對(duì)象字面量,工廠模式,構(gòu)造函數(shù)模式,原型模式,結(jié)合構(gòu)造函數(shù)和原型模式,原型動(dòng)態(tài)模式 ,感興趣的朋友參考下

JavaScript中創(chuàng)建對(duì)象的模式匯總

**JavaScript創(chuàng)建對(duì)象模式:

對(duì)象字面量
工廠模式
構(gòu)造函數(shù)模式
原型模式
結(jié)合構(gòu)造函數(shù)和原型模式
原型動(dòng)態(tài)模式
**

面向?qū)ο蟮恼Z(yǔ)言大都有一個(gè)類的概念,通過(guò)類可以創(chuàng)建多個(gè)具有相同方法和屬性的對(duì)象。雖然從技術(shù)上講,javascript是一門(mén)面向?qū)ο蟮恼Z(yǔ)言,但是javascript沒(méi)有類的概念,一切都是對(duì)象。任意一個(gè)對(duì)象都是某種引用類型的實(shí)例,都是通過(guò)已有的引用類型創(chuàng)建;引用類型可以是原生的,也可以是自定義的。

1、對(duì)象字面量

var person = {
    name : 'Nicholas';
    age : '22';
    job :"software Engineer"
    sayName: function() {
      alter(this.name);
  }
}

例子中創(chuàng)建一個(gè)名為person的對(duì)象,并為它添加了三個(gè)屬性(name,age,job)和一個(gè)方法(sayName()),其中,sayName()方法用于顯示this.name(被解析為person.name)的值。

對(duì)象字面量可以用來(lái)創(chuàng)建單個(gè)對(duì)象,但這個(gè)方法有個(gè)明顯的缺點(diǎn):使用同一個(gè)接口創(chuàng)建很多對(duì)象,會(huì)產(chǎn)生大量重復(fù)的代碼。

2、工廠模式

工廠模式是軟件工程領(lǐng)域中一種廣為人知的設(shè)計(jì)模式,工廠模式抽象了創(chuàng)建具體對(duì)象的過(guò)程,用函數(shù)來(lái)封裝以特定的接口創(chuàng)建對(duì)象的細(xì)節(jié)。

function createPerson(name,age,job){
  var o = new object{};
  o.name=name;
  o.age=age;
  o.job=job;
  o.sayName=function(){
    alert(this.name);
  };
  return o;
}
var person1=creatPerson("Nicholas",22,"software Engineer");
var person2=creatPerson("Greg",24,"student");

函數(shù)creatPerson{}能夠根據(jù)接受的參數(shù)構(gòu)建一個(gè)包含所有必要信息的Person對(duì)象??梢詿o(wú)數(shù)次的調(diào)用這個(gè)函數(shù),每次都會(huì)返回一個(gè)包含三個(gè)屬性一個(gè)方法的對(duì)象。

工廠模型雖然解決了創(chuàng)建多個(gè)相似對(duì)象的問(wèn)題,卻沒(méi)有解決對(duì)象識(shí)別的問(wèn)題(即怎么知道一個(gè)對(duì)象的類型)。

3、構(gòu)造函數(shù)模式

function Person(name,age,job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function() {
    alert(this.name);
  }
}
//通過(guò)new操作符創(chuàng)建Person的實(shí)例
var person1 = new Person("Nicholas",22,"software Engineer");
var person2 = new Person("Greg",24,"student");
person1.sayName(); //Nicholas
person2.sayName(); //Greg

與工廠模式不同的是

沒(méi)有顯示的創(chuàng)建對(duì)象

直接將屬性和方法賦給了this對(duì)象

沒(méi)有return語(yǔ)句

創(chuàng)建Person的新實(shí)例,必須使用new操作符。調(diào)用構(gòu)造函數(shù)的4個(gè)步驟:

創(chuàng)建一個(gè)新對(duì)象

將構(gòu)造函數(shù)的作用域賦給新對(duì)象(this指向了這個(gè)新對(duì)象)

執(zhí)行構(gòu)造函數(shù)中的代碼

返回新對(duì)象

這個(gè)例子中創(chuàng)建的所有對(duì)象既是Object的實(shí)例,也是Person實(shí)例。可以通過(guò)instanceof操作符驗(yàn)證。

alert(person1 instanceof Object);//true

構(gòu)造函數(shù)模式也有自己的問(wèn)題,實(shí)際上,sayName方法在每個(gè)實(shí)例上都會(huì)被重新創(chuàng)建一次,需要注意的是,通過(guò)實(shí)例化創(chuàng)建的方法并不相等,以下代碼可以證明

alert(person1.sayName == person2.sayName);//false

可以將方法移到構(gòu)造器的外部作為全局函數(shù)來(lái)解決這個(gè)問(wèn)題。

function Person(name,age,job) {
  this.name = name;
  this.age = age;
  this.job = job;  
}
function sayName() {
    alert(this.name);
  }

在全局下創(chuàng)建的全局函數(shù)實(shí)際上只能被經(jīng)由Person創(chuàng)建的實(shí)例調(diào)用,這就有點(diǎn)名不副實(shí)了;如果對(duì)象需要定義很對(duì)方法,那么就要定義很多個(gè)全局函數(shù),缺少封裝性。

4、原型模式

JavaScript中創(chuàng)建的每個(gè)函數(shù)都有一個(gè)prototype(原型)屬性,它是一個(gè)指針,指向一個(gè)對(duì)象,包含了可以由特定類型的所有實(shí)例共享的屬性和方法(讓所有的對(duì)象實(shí)例共享它的屬性和方法)

function Person() {}
  Person.prototype.name ="Nicholas";
  Person.prototype.age = 22;
  Person.prototype.job = "software Engineer";  
  Person.prototype.sayName(){
    alert(this.name);
  };
 var person1 = new Person();
 person1.sayName(); //Nicholas
alert(person1.sayName == person2.sayName);//true

以上代碼做了這幾件事情:

定義了一個(gè)構(gòu)造函數(shù)Person,Person函數(shù)自動(dòng)獲得一個(gè)prototype屬性,該屬性默認(rèn)只包含一個(gè)指向Person的constructor屬性
通過(guò)Person.prototype添加三個(gè)屬性,和一個(gè)方法

創(chuàng)建一個(gè)Person的實(shí)例,隨后在實(shí)例上調(diào)用了sayName()方法

使用Person構(gòu)造函數(shù)和Person.prototype創(chuàng)建實(shí)例的代碼為例,展示個(gè)對(duì)象之間的關(guān)系

使用Person構(gòu)造函數(shù)和Person.prototype創(chuàng)建實(shí)例的代碼為例,展示個(gè)對(duì)象之間的關(guān)系

使用Person構(gòu)造函數(shù)和Person.prototype創(chuàng)建實(shí)例的代碼為例,展示個(gè)對(duì)象之間的關(guān)系 

圖中展示了Person構(gòu)造函數(shù)、Person的原型屬性以及Person的兩個(gè)實(shí)例,之間的關(guān)系。Person.prototype指向了原型對(duì)象,Person.prototype.constructor有指回了Person。原型對(duì)象中除了包含constructor屬性,還包含后來(lái)添加的其他屬性和方法,Person的兩個(gè)實(shí)例person1和person2都包含一個(gè)內(nèi)部屬性,該屬性僅指向Person.prototype。

sayName()方法的調(diào)用過(guò)程:

在person1實(shí)例上查找logName()方法,發(fā)現(xiàn)沒(méi)有這個(gè)方法,于是追溯到person1的原型

在person1的原型上查找sayame()方法,有這個(gè)方法,于是調(diào)用該方法

基于這樣一個(gè)查找過(guò)程,我們可以通過(guò)在實(shí)例上定義原型中的同名屬性,來(lái)阻止該實(shí)例訪問(wèn)原型上的同名屬性,需要注意的是,這樣做并不會(huì)刪除原型上的同名屬性,僅僅是阻止實(shí)例訪問(wèn)。

function Person() {}
  Person.prototype.name ="Nicholas";
  Person.prototype.age = 22;
  Person.prototype.job = "software Engineer";  
  Person.prototype.sayName(){
    alert(this.name);
  };
 var person1 = new Person();
 var person2 = new Person();
 person1.name="Greg"
alert(person1.name) //Greg 來(lái)自實(shí)例
alert(person2.name) //Nicholas 來(lái)自原型

使用delete操作符可以完全刪除實(shí)例屬性

delete person1.name;
alert(person1.name) //Nicholas 來(lái)自原型

使用hasOwnProperty()方法可以檢測(cè)一個(gè)屬性是存在于實(shí)例還是原型中

function Person() {}
  Person.prototype.name ="Nicholas";
  Person.prototype.age = 22;
  Person.prototype.job = "software Engineer";  
  Person.prototype.sayName(){
    alert(this.name);
  };
 var person1 = new Person();
 var person2 = new Person();
 alert(person1,hasOwnProperty("name"));//false
 person1.name="Greg"
alert(person1.name) //Greg 來(lái)自實(shí)例
 alert(person1,hasOwnProperty("name"));//true
alert(person2.name) //Nicholas 來(lái)自原型
 alert(person2,hasOwnProperty("name"));//false
 delete person1.name;
alert(person1.name) //Nicholas 來(lái)自原型
 alert(person1,hasOwnProperty("name"));//false

下圖展示了在不同情況下實(shí)例與原型之間的關(guān)系

這里寫(xiě)圖片描述

簡(jiǎn)單的原型語(yǔ)法

function Person() {}
 Person.prototype={
 name :"Nicholas",
 age : 22,
 job : "software Engineer", 
 sayName:function(){
    alert(this.name);
    }
  };

在上面的代碼中constructor屬性不再指向Person了,通過(guò)constructor無(wú)法確定對(duì)象的類型了??梢韵裣旅孢@樣特意將他設(shè)置回適當(dāng)?shù)闹?/p>

function Person() {}
 Person.prototype={
 constructor:Person,
 name :"Nicholas",
 age : 22,
 job : "software Engineer",  
 sayName:function(){
    alert(this.name);
    }
  };

重設(shè)constructor屬性會(huì)導(dǎo)致它的[[Enumerable]]特性被設(shè)置為true,默認(rèn)情況,原生的constructor屬性是不可枚舉的,可以使用Object.defineProperty()方法來(lái)改變

Object.defineProperty(Person.prototype,"constructor",{
  enumerable:false,
  value:Person
});

原型中查找值的過(guò)程是一次搜索,原型對(duì)象所做的任何修改都能從實(shí)例上立即反應(yīng)出來(lái)

var friend=new Person();
Person.prototype.sayHi=function(){
  alert("hi);
}
friend,sayHi();//"hi"(沒(méi)有問(wèn)題)

person實(shí)例是在添加新方法之前創(chuàng)建的,但仍可以訪問(wèn)新添加的方法,原因是實(shí)例與原型之間的松散連接關(guān)系
重寫(xiě)原型對(duì)象后的情況

function Person() {}
var friend=new Person();
 Person.prototype={
 name :"Nicholas",
 age : 22,
 job : "software Engineer", 
 sayName:function(){
    alert(this.name);
    }
  };
  friend.sayName();//error

調(diào)用friend.sayName()時(shí)發(fā)生錯(cuò)誤的原因是,friend指向的原型中不包含以該字段命名的屬性,如下圖。

這里寫(xiě)圖片描述 

原型對(duì)象的問(wèn)題

原型對(duì)象省略了為構(gòu)造函數(shù)傳遞初始化參數(shù)這一環(huán)節(jié),所有勢(shì)力在默認(rèn)情況下都取得相同的屬性值。原型模型最大的問(wèn)題是有其共享本性所導(dǎo)致的。當(dāng)原型模型包含引用類型的屬性來(lái)說(shuō),問(wèn)題就比較嚴(yán)重了。來(lái)看下面的例子。

function Person() {}
 Person.prototype={
 constructor:Person,
 name :"Nicholas",
 age : 22,
 job : "software Engineer",  
 friends:["Shelby","Court"],
 sayName:function(){
    alert(this.name);
    }
  };
  var person1=new Person();
  var person2=new Person();
  person1.friend.push("Van");
  alert(person1.friends);//"Shelby,Court,Van"
  alert(person2.friends);//"Shelby,Court,Van"
 alert(person1.friends==person2.friends);//true

5、組合使用構(gòu)造函數(shù)模式和原型模式

組合使用構(gòu)造函數(shù)模式和原型模式中,構(gòu)造函數(shù)用于定義實(shí)例屬性,原型模型用于定義方法和共享的屬性。這樣每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,同時(shí)也可以共享對(duì)方法的引用,最大限度的節(jié)省了內(nèi)存。

function Person(name,age,job) {
  this.name = name;
  this.age = age;
  this.job = job;  
  this.friends=["Shelby","Court"];
}
Person.prototype={
 constructor:Person,
 sayName:function(){
    alert(this.name);
    }
  }
var person1=new Person("Nicholas",22,"software Engineer");
var person2 = new Person("Greg",24,"student");
person1.friend.push("Van");
  alert(person1.friends);//"Shelby,Court,Van"
  alert(person2.friends);//"Shelby,Court"
 alert(person1.friends==person2.friends);//false
 alert(person1.sayName==person2.sayName);//true

6、動(dòng)態(tài)原型模式

原型動(dòng)態(tài)模式將需要的所有信息都封裝到構(gòu)造函數(shù)中,通過(guò)if語(yǔ)句判斷原型中的某個(gè)屬性是否存在,若不存在(在第一次調(diào)用這個(gè)構(gòu)造函數(shù)的時(shí)候),執(zhí)行if語(yǔ)句內(nèi)部的原型初始化代碼。

function Person(name,age) {
  this.name = name;
  this.age = age;
  this.job =job;
//方法
  if(typeof this.sayName != 'function') {
  Person.prototype.sayName = function() {
      alert(this.name);
    };   
  }
}
var friend = new Person('Nicholas','22','Software Engineer');//初次調(diào)用構(gòu)造函數(shù),此時(shí)修改了原型
var person2 = new Person('amy','21');//此時(shí)sayName()方法已經(jīng)存在,不會(huì)再修改原型

推薦閱讀:

js面向?qū)ο笾R?jiàn)創(chuàng)建對(duì)象的幾種方式(工廠模式、構(gòu)造函數(shù)模式、原型模式)

以上所述是小編給大家介紹的JavaScript中創(chuàng)建對(duì)象的模式,希望對(duì)大家有所幫助!

相關(guān)文章

  • 淺談Javascript事件模擬

    淺談Javascript事件模擬

    事件是用來(lái)描述網(wǎng)頁(yè)中某一特定有趣時(shí)刻的,眾所周知事件通常是在由用戶和瀏覽器進(jìn)行交互時(shí)觸發(fā),其實(shí)不然,通過(guò)Javascript可以在任何時(shí)間觸發(fā)特定的事件,并且這些事件與瀏覽器創(chuàng)建的事件是相同的
    2012-06-06
  • 手把手教你如何開(kāi)發(fā)屬于自己的一款小程序

    手把手教你如何開(kāi)發(fā)屬于自己的一款小程序

    相信大家都知道小程序是一種不需要下載安裝即可使用的應(yīng)用,下面這篇文章主要給大家介紹了關(guān)于如何開(kāi)發(fā)屬于自己的一款小程序的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 扒一扒JavaScript 預(yù)解釋

    扒一扒JavaScript 預(yù)解釋

    這篇文章主要介紹了JavaScript 預(yù)解釋,包含帶var關(guān)鍵字預(yù)解釋、帶function關(guān)鍵字預(yù)解釋,需要的朋友可以參考下
    2015-01-01
  • javascript獲取四位數(shù)字或者字母的隨機(jī)數(shù)

    javascript獲取四位數(shù)字或者字母的隨機(jī)數(shù)

    這篇文章主要介紹了javascript獲取四位數(shù)字或者字母的隨機(jī)數(shù),需要的朋友可以參考下
    2015-01-01
  • 控制頁(yè)面按鈕在后臺(tái)執(zhí)行期間不重復(fù)提交的JS方法

    控制頁(yè)面按鈕在后臺(tái)執(zhí)行期間不重復(fù)提交的JS方法

    下面的代碼可以避免這種情況的發(fā)生,要等第一次執(zhí)行完返回?cái)?shù)據(jù)到前臺(tái)后才能提交第二次。
    2013-06-06
  • 如何利用Javascript生成平滑曲線詳解

    如何利用Javascript生成平滑曲線詳解

    相信大家都遇到過(guò),在各種圖表框架中經(jīng)常會(huì)有將一段折線平滑的需求,不僅能給用戶帶來(lái)一種柔和的感覺(jué),還能美化界面,讓折線看起來(lái)沒(méi)那么生硬,這篇文章主要給大家介紹了關(guān)于如何利用Javascript生成平滑曲線的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • javascript按鈕禁用和啟用的效果實(shí)例代碼

    javascript按鈕禁用和啟用的效果實(shí)例代碼

    這篇文章主要介紹了javascript按鈕禁用和啟用的效果實(shí)例代碼,需要的朋友可以參考下
    2017-10-10
  • js對(duì)象繼承之原型鏈繼承實(shí)例

    js對(duì)象繼承之原型鏈繼承實(shí)例

    這篇文章主要介紹了js對(duì)象繼承之原型鏈繼承,以實(shí)例形式分析了原型鏈繼承的實(shí)現(xiàn)方法與注意事項(xiàng),具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-01-01
  • Redux實(shí)現(xiàn)組合計(jì)數(shù)器的示例代碼

    Redux實(shí)現(xiàn)組合計(jì)數(shù)器的示例代碼

    本篇文章主要介紹了Redux實(shí)現(xiàn)組合計(jì)數(shù)器的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • javascript使用閉包模擬對(duì)象的私有屬性和方法

    javascript使用閉包模擬對(duì)象的私有屬性和方法

    本文給大家簡(jiǎn)單介紹了在一個(gè)項(xiàng)目中涉及到的javascript使用閉包模擬對(duì)象的私有屬性和方法,這里記錄下來(lái),分享給大家。
    2016-10-10

最新評(píng)論