电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

詳解 javascript對象創建模式

瀏覽:114日期:2023-10-09 16:08:09

創建模式

在javascript中,主要有以下幾種創建模式:

工廠模式構造函數模式原型模式組合模式動態原型模式寄生構造函數模式穩妥構造模式

工廠模式

工廠模式是軟件工程領域一種廣為人知的設計模式。javascript實現方式:

function createPerson(name, obj, job) { var o = new Object(); o.name = name; o.obj = obj; o.job = job; o.sayName = function() { alert(this.name); } return o; } var person1 = createPerson('Nicholas', 29, 'software Enginner'); var person2 = createPerson('Greg', 27, 'Doctor');

工廠模式雖然解決了創建多個相似對象的問題,但卻沒有解決對象識別問題

構造函數模式

function Person(name, age, job) { this.name = name; this.age = name; this.job = name; this.sayName = function () { alert(this.name); } } var person1 = new Person('Nicholas', 29, 'Software Engineer'); var person2 = new Person('Greg', 27, 'Doctor'); person1 instanceof Person; // true person1 instanceof Object; // true person2 instanceof Person; // true person2 instanceof Object; // true

new操作符實現原理請查看文章附錄

不同于工廠模式,構造函數模式

沒有顯示創建對象

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

沒有return語句

解決了對象識別問題

但是構造函數模式同樣存在問題,就是每個方法都要在每個實例上重新申明一遍。person1和person2都有一個名為 sayName() 的方法,但那兩個方法不是同一個Function實例。(在javascript中,函數實質上也是對象,因此每定義一個函數,也就是實例化一個對象。)

通過吧函數定義轉移到構造函數外部可以解決這個問題:

function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName() { alert(this.name); } var person1 = new Person('Nicholas', 29, 'Software Engineer'); var person2 = new Person('Greg', 27, 'Doctor');

但這種方式又帶來了一個新的問題,我們在全局創建了一個全局函數。

需要注意一點,按照慣例,構造函數始終應該以一個大寫字母開頭,而非構造函數應該以一個小寫字母開頭。這主要用于區別構造函數和非構造函數,因為構造函數本身也是函數。

原型模式

我們創建的每個函數都有一個 prototype (原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途可以由特定類型的所有實例共享的屬性和方法。

函數原型對象請查看附錄

通過原型模式創建對象,我們不必在構造函數中定義對象實例的信息,同時實例化多個對象,每個對象不會再申明一個新的函數。

可以看到, person1.sayName 和 person2.sayName 都指向了同一個函數。

但是原型模式的缺點也是顯而易見的。

首先原型模式省略了構造函數模式傳遞參數這一環節,結果導致所有實例的初始值在默認情況下都是相同的屬性值。

更重要的是,因為將屬性和方法都放置在原型對象上,實質上原型上的屬性是 被所有實例所共享的 。對于包含基本值的屬性還表現正常,改變屬性值,只是在實例上添加一個同名屬性。但對于引用類型值的屬性來說,這可能是個災難。

function Person() {} Person.prototype = { constructor: Person, name: 'Nicholas', age: 29, job: 'Software Engineer', friends: ['shelby', 'Court'], sayName: function() { alert(this.name); } }; var person1 = new Person(); var person2 = new Person(); person1.friends.push('Van'); person1.friends; // ['shelby', 'Court', 'Van'] person2.friends; // ['shelby', 'Court', 'Van']

組合模式

創建自定義類型最常見的方式,就是組合使用構造函數模式和原型模式。構造模式用于定義實例屬性,而原型模式用于定義方法和共享屬性。

這樣,每個實例都會有自己的一份實例屬性副本,但同時又共享方法的引用。

function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.friends = ['Shelby', 'Court']; } Person.prototype.sayName = function() { alert(this.name); } var person1 = new Person('Nicholas', 29, 'Software Enginner'); var person2 = new Person('Greg', 27, 'Doctor'); person1.friends.push('Van'); person1.firends; // ['Shelby', 'Court', 'Van']; person2.firends; // ['Shelby', 'Court'] person1.firends === person2.firends; // false person1.sayName === person2.sayName; // true

動態原型模式

function Person(name, age, job) { this.name = name; this.age = age; this.job = job;if (typeof this.sayName != 'function') { Person.prototype.sayName = function() {alert(this.name); } } }

寄生構造函數模式

寄生模式的基本概念就是創建一個函數,該函數的作用僅僅是封裝創建對象的代碼,然后再返回新創建的對象。

function Person(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job.o.sayName = function() { alert(this.name); } } var person1 = new Person('Nicholas', 29, 'Software Engineer'); person1.sayName(); // 'Nicholas'

看起來,除了使用new操作符之外,這個模式和工廠模式其實是一模一樣的。這個模式可以在特殊的情況下用來作為對象創建構造函數。假設我們需要一個具有額外方法的特殊數組類型。由于不能直接修改Array構造函數,因此可以使用這個模式。

function SpecialArray() { var values = [];values.push.push(values, arguments); values.toPipedString = function() { return this.join('|'); }return values; } var colors = new SpecialArray('red', 'blue', 'green'); colors.toPipedString(); // 'red|blue|green'

該模式主要缺點:返回的對象和構造函數或構造函數的原型屬性間沒有關系,不·能依賴instanceof來確定對象類型。在其他模式能夠使用的情況下,盡量不要使用這種模式。

穩妥構造函數模式

function Person(name, age, job) { var o = new Object(); var name = name; var age = age; var job = jbo;o.sayName = function() { alert(name); } } var person1 = Person('Nicholas', 29, 'Software Enginner'); firend.sayName(); // 'Nicholas' 附錄 new 操作符

new操作符實際上會經歷4個步驟:

創建一個空的簡單JavaScript對象(即**{}**); 鏈接該對象(設置該對象的constructor)到另一個對象 ; 將步驟1新創建的對象作為**this**的上下文 ; 如果該函數沒有返回對象,則返回**this**。

function new(func) { var o = {}; o.__proto__ = func.prototype; var result = func.apply(o, arguments); return typeof result === 'object' ? object : o; }

函數原型對象

理解原型對象

無論什么時候,只要創建一個新函數,就會根據一組特定的規則為該函數創建一個prototype屬性,這個屬性指向函數的原型對象。在默認情況下,所有原型對象都會自動獲得一個construtor(構造函數)屬性,這個屬性包含一個指向prototype屬性所在函數的指針。

在創建了一個自定義的構造函數之后,其原型對象只會取得construtoe屬性,至于其他屬性,則都是從Object繼承而來。當調用構造函數創建一個新實例時,該實例的內部將包含一個指針(內部屬性),指向構造函數的原型對象,這個指針叫[[Prototype]]。在多數瀏覽器中,每個對象都支持一個屬性__proto__來調用[[Prototype]]。

詳解 javascript對象創建模式

雖然所有實現都無法直接訪問[[Prototype]],但可以通過isPrototype方法來確定對象之間是否存在關系。

我們測試了person1和person2,都返回了true。因為他們內部都有一個指向Person.prototype的指針。

Object.getPrototype()可以返回對象的原型對象。

每當代碼讀取某個對象的屬性時,都會執行一次搜索,目標是具有給定名字的屬性。搜索首先會從對象本身開始,如果在實例中找到了對應的屬性,則返回該屬性的值。如果沒找到,則繼續搜索指針指向的原型對象。這也是為什么我們在person1和person2兩個實例中,并沒有定義sayName這個屬性,但仍能夠正常使用。我們在調用person1.sayName()是,會執行兩次搜索。首先,解析器會問:“實例person1有sayName屬性嗎?”,答:“沒有”。然后他繼續搜索,再問:“person1的原型有sayName屬性嗎?”,答:“有”。于是,它就讀取保存在原型中的函數。

雖然我們能夠通過實例訪問原型的屬性,但卻不能重新原型的屬性。如果我們在實例上添加屬性名,而這個屬性名又與原型中的屬性名相同,即我們希望在實例中重寫屬性。

function Person() {} Person.prototype.name = ’Nicholas’; var person1 = new Person(); var person2 = new Person(); person1.name === person2.name; // true person1.name = ’Greg’; person1.name === person2.name; // false person1.name; // ’Greg’ person2.name; // ’Nicholas’ person1.__proto__.name; // ’Nicholas’

事實上,當我們重寫原型屬性時,只是在實例上添加了一個新屬性。當我們把實例上的屬性刪除后,又會暴露出原型屬性。

delete person1.name; person1.name; // ’Nicholas’

使用hasOwnProperty()函數能判斷屬性是否在實例上。

person1.hasOwnProperty(’name’); // false person1.name = ’Greg’; person1.hasOwnProperty(’name’); // true

以上就是詳解 javascript對象創建模式的詳細內容,更多關于Java 創建模式的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 天坛家具官网| 西安文都考研官网_西安考研辅导班_考研培训机构_西安在职考研培训 | 洁净实验室工程-成都手术室净化-无尘车间装修-四川华锐净化公司-洁净室专业厂家 | 袋式过滤器,自清洗过滤器,保安过滤器,篮式过滤器,气体过滤器,全自动过滤器,反冲洗过滤器,管道过滤器,无锡驰业环保科技有限公司 | 异噻唑啉酮-均三嗪-三丹油-1227-中北杀菌剂厂家 | 卫生人才网-中国专业的医疗卫生医学人才网招聘网站! | 楼承板-钢筋楼承板-闭口楼承板-无锡优贝斯楼承板厂 | 运动木地板厂家_体育木地板安装_篮球木地板选购_实木运动地板价格 | 联系我们老街华纳娱乐公司官网19989979996(客服) | 四探针电阻率测试仪-振实密度仪-粉末流动性测定仪-宁波瑞柯微智能 | 光栅尺厂家_数显表维修-苏州泽升精密机械 | 洛阳防爆合格证办理-洛阳防爆认证机构-洛阳申请国家防爆合格证-洛阳本安防爆认证代办-洛阳沪南抚防爆电气技术服务有限公司 | 天津仓储物流-天津电商云仓-天津云仓一件代发-博程云仓官网 | 模型公司_模型制作_沙盘模型报价-中国模型网 | 聚氨酯催化剂K15,延迟催化剂SA-1,叔胺延迟催化剂,DBU,二甲基哌嗪,催化剂TMR-2,-聚氨酯催化剂生产厂家 | 无压烧结银_有压烧结银_导电银胶_导电油墨_导电胶-善仁(浙江)新材料 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 柴油发电机组_柴油发电机_发电机组价格-江苏凯晨电力设备有限公司 | 暖气片十大品牌厂家_铜铝复合暖气片厂家_暖气片什么牌子好_欣鑫达散热器 | 山东风淋室_201/304不锈钢风淋室净化设备厂家-盛之源风淋室厂家 翻斗式矿车|固定式矿车|曲轨侧卸式矿车|梭式矿车|矿车配件-山东卓力矿车生产厂家 | 流水线电子称-钰恒-上下限报警电子秤-上海宿衡实业有限公司 | 天津中都白癜风医院_天津白癜风医院_天津治疗白癜风 | 东莞螺杆空压机_永磁变频空压机_节能空压机_空压机工厂批发_深圳螺杆空压机_广州螺杆空压机_东莞空压机_空压机批发_东莞空压机工厂批发_东莞市文颖设备科技有限公司 | 自动螺旋上料机厂家价格-斗式提升机定制-螺杆绞龙输送机-杰凯上料机 | 咖啡加盟,咖啡店加盟连锁品牌-卡小逗 | 闪蒸干燥机-喷雾干燥机-带式干燥机-桨叶干燥机-[常州佳一干燥设备] | 广东恩亿梯电源有限公司【官网】_UPS不间断电源|EPS应急电源|模块化机房|电动汽车充电桩_UPS电源厂家(恩亿梯UPS电源,UPS不间断电源,不间断电源UPS) | LNG鹤管_内浮盘价格,上装鹤管,装车撬厂家-连云港赛威特机械 | PO膜_灌浆膜及地膜供应厂家 - 青州市鲁谊塑料厂 | 高压油管,液压接头,液压附件-烟台市正诚液压附件 | 【中联邦】增稠剂_增稠粉_水性增稠剂_涂料增稠剂_工业增稠剂生产厂家 | 私人别墅家庭影院系统_家庭影院音响_家庭影院装修设计公司-邦牛影音 | 喷漆房_废气处理设备-湖北天地鑫环保设备有限公司 | 水厂污泥地磅|污泥处理地磅厂家|地磅无人值守称重系统升级改造|地磅自动称重系统维修-河南成辉电子科技有限公司 | EDLC超级法拉电容器_LIC锂离子超级电容_超级电容模组_软包单体电容电池_轴向薄膜电力电容器_深圳佳名兴电容有限公司_JMX专注中高端品牌电容生产厂家 | 考勤系统_人事考勤管理系统_本地部署BS考勤系统_考勤软件_天时考勤管理专家 | 控显科技 - 工控一体机、工业显示器、工业平板电脑源头厂家 | 玻璃钢罐_玻璃钢储罐_盐酸罐厂家-河北华盛节能设备有限公司 | 甲级防雷检测仪-乙级防雷检测仪厂家-上海胜绪电气有限公司 | 复合土工膜厂家|hdpe防渗土工膜|复合防渗土工布|玻璃纤维|双向塑料土工格栅-安徽路建新材料有限公司 | 南方珠江-南方一线电缆-南方珠江科技电缆-南方珠江科技有限公司 南汇8424西瓜_南汇玉菇甜瓜-南汇水蜜桃价格 |