最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

1、對象字面量

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

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

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

2、工廠模式

工廠模式是軟件工程領(lǐng)域中一種廣為人知的設(shè)計模式,工廠模式抽象了創(chuàng)建具體對象的過程,用函數(shù)來封裝以特定的接口創(chuàng)建對象的細節(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)建一個包含所有必要信息的Person對象??梢詿o數(shù)次的調(diào)用這個函數(shù),每次都會返回一個包含三個屬性一個方法的對象。

工廠模型雖然解決了創(chuàng)建多個相似對象的問題,卻沒有解決對象識別的問題(即怎么知道一個對象的類型)。

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

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

與工廠模式不同的是

沒有顯示的創(chuàng)建對象

直接將屬性和方法賦給了this對象

沒有return語句

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

創(chuàng)建一個新對象

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

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

返回新對象

這個例子中創(chuàng)建的所有對象既是Object的實例,也是Person實例??梢酝ㄟ^instanceof操作符驗證。

alert(person1 instanceof Object);//true

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

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

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

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

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

4、原型模式

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

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òu)造函數(shù)Person,Person函數(shù)自動獲得一個prototype屬性,該屬性默認只包含一個指向Person的constructor屬性
通過Person.prototype添加三個屬性,和一個方法

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

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

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

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

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

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

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

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

基于這樣一個查找過程,我們可以通過在實例上定義原型中的同名屬性,來阻止該實例訪問原型上的同名屬性,需要注意的是,這樣做并不會刪除原型上的同名屬性,僅僅是阻止實例訪問。

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 來自實例
alert(person2.name) //Nicholas 來自原型

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

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

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

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 來自實例
 alert(person1,hasOwnProperty("name"));//true
alert(person2.name) //Nicholas 來自原型
 alert(person2,hasOwnProperty("name"));//false
 delete person1.name;
alert(person1.name) //Nicholas 來自原型
 alert(person1,hasOwnProperty("name"));//false

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

這里寫圖片描述

簡單的原型語法

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

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

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

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

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

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

var friend=new Person();
Person.prototype.sayHi=function(){
  alert("hi);
}
friend,sayHi();//"hi"(沒有問題)

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

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()時發(fā)生錯誤的原因是,friend指向的原型中不包含以該字段命名的屬性,如下圖。

這里寫圖片描述 

原型對象的問題

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

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ù)用于定義實例屬性,原型模型用于定義方法和共享的屬性。這樣每個實例都會有自己的一份實例屬性的副本,同時也可以共享對方法的引用,最大限度的節(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、動態(tài)原型模式

原型動態(tài)模式將需要的所有信息都封裝到構(gòu)造函數(shù)中,通過if語句判斷原型中的某個屬性是否存在,若不存在(在第一次調(diào)用這個構(gòu)造函數(shù)的時候),執(zhí)行if語句內(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ù),此時修改了原型
var person2 = new Person('amy','21');//此時sayName()方法已經(jīng)存在,不會再修改原型

推薦閱讀:

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

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

相關(guān)文章

  • javascript函數(shù)中參數(shù)傳遞問題示例探討

    javascript函數(shù)中參數(shù)傳遞問題示例探討

    本節(jié)主要與大家探討下javascript函數(shù)中參數(shù)傳遞問題,有不明白的朋友可以參考下
    2014-07-07
  • JavaScript利用HTML DOM進行文檔操作的方法

    JavaScript利用HTML DOM進行文檔操作的方法

    DOM是W3C制定的用于訪問諸如XML和XHTML等結(jié)構(gòu)化文檔的標準。通過本文給大家介紹JavaScript利用HTML DOM進行文檔操作的方法,需要的朋友參考下吧
    2016-03-03
  • javascript時間函數(shù)基礎(chǔ)介紹

    javascript時間函數(shù)基礎(chǔ)介紹

    這篇文章主要介紹了javascript中提供了Date對象來進行時間和日期的計算,這里簡單的介紹下, 方便需要的朋友
    2013-03-03
  • Java/JS獲取flash高寬的具體方法

    Java/JS獲取flash高寬的具體方法

    本文為大家詳細介紹下使用Java/JS如何獲取flash的高寬,下面有個不錯的示例,感興趣的朋友可以參考下,希望對大家有所幫助
    2013-12-12
  • javascript DOM設(shè)置樣式詳細說明和示例代碼

    javascript DOM設(shè)置樣式詳細說明和示例代碼

    JavaScript也可以用來修改DOM元素的樣式,我們可以使用style屬性來訪問和修改元素的樣式屬性,這篇文章主要給大家介紹了關(guān)于javascript DOM設(shè)置樣式詳細說明和示例代碼的相關(guān)資料,需要的朋友可以參考下
    2024-06-06
  • 前端JavaScript獲取電池信息

    前端JavaScript獲取電池信息

    受到同事啟發(fā),突然發(fā)現(xiàn)了幾個有趣又實用的web api,下面這篇文章主要給大家介紹了關(guān)于前端JavaScript獲取電池信息的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-04-04
  • 微信小程序用戶授權(quán)最佳實踐指南

    微信小程序用戶授權(quán)最佳實踐指南

    這篇文章主要給大家介紹了關(guān)于微信小程序用戶授權(quán)最佳實踐的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • setTimeout和setInterval的區(qū)別你真的了解嗎?

    setTimeout和setInterval的區(qū)別你真的了解嗎?

    setTimeout和setInterval這兩個函數(shù), 大家肯定都不陌生, 但可能并不是每個用過這兩個方法的同學(xué), 都了解其內(nèi)部的實質(zhì)
    2011-03-03
  • 詳解Webwork中Action 調(diào)用的方法

    詳解Webwork中Action 調(diào)用的方法

    這篇文章主要介紹了詳解Webwork中Action 調(diào)用的方法的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • jsvascript圖像處理—(計算機視覺應(yīng)用)圖像金字塔

    jsvascript圖像處理—(計算機視覺應(yīng)用)圖像金字塔

    上一篇文章,我們講解了邊緣梯度計算函數(shù),這篇文章我們來了解圖像金字塔;圖像金字塔被廣泛用于計算機視覺應(yīng)用中;圖像金字塔是一個圖像集合,集合中所有的圖像都源于同一個原始圖像,而且是通過對原始圖像連續(xù)降采樣獲得的
    2013-01-01

最新評論

建德市| 重庆市| 那坡县| 宝应县| 古丈县| 宜君县| 南通市| 绥中县| 富裕县| 昌平区| 商南县| 瑞丽市| 始兴县| 十堰市| 吴江市| 保定市| 庆云县| 承德县| 安顺市| 岳阳县| 涟水县| 两当县| 隆昌县| 平乐县| 东宁县| 嘉义市| 洛宁县| 勃利县| 潼关县| 天台县| 宜兰市| 汝州市| 酒泉市| 施秉县| 通化市| 威信县| 灵寿县| 乳山市| 临沧市| 遵化市| 仪征市|