內容比較基礎,高手請繞過!
Javascript作為弱類型語言,和Java、php等服務端指令碼語言相比,擁有極強的靈活性。對於小型的web需求,在編寫javascript時,可以選擇面向過程的方式編程,顯得高效;但在實際工作中,遇到的項目需求和架構較大的情況下,選擇物件導向的方式編程顯得尤其重要,Javascript原生文法中沒有提供表述物件導向語言特性的關鍵字和文法(如extends、implement)。為了實現這些物件導向的特性,需要額外編寫一些代碼,如下。
在開始使用OO特性之前,還需要考慮使用介面、繼承所帶來的弊端。封裝、介面、繼承都將使代碼結構變得複雜,對於編碼新手有較高的要求,對於別人接受你的項目成本也提高了,在團隊協作中需要根據具體需求斟酌,不要為了秀技術而寫代碼;同時,封裝和介面都將帶來一些額外的記憶體開銷,有些可以忽略不計,有些 則是得不償失,需要注意。
一、封裝
var book = (function(){ var COUNT = 0; //靜態私人方法 function checkISBN(isbn){ return true; } //構造器 var ctor = function(id,name,isbn){ var _id,_name,_isbn this.setId= function(id){ _id=id; } this.getId = function(){ return _id; } this.setName = function(name){ _name = name; } this.getName = function(){ return name; } this.setIsbn = function(isbn){ _isbn = isbn; } this.getIsbn = function(){ return isbn; } if(checkISBN){ COUNT++; } this.setName(name); this.setId(id); this.setIsbn(isbn); } ctor.getCount = function(){ return COUNT; } return ctor; })();//靜態、共用方法book.buyCount = function(count){ return count;}book.prototype = { display:function(){ }}var b = new book();b.getCount();b.display();
二、介面
/** * 介面:實現多個類的共同性。讓彼此不想關的對象也能被同等對待。 */var Interface = function(name,method){ if(arguments.length < 2){ throw new Error("xxx"); } this.name = name; this.method = []; for(var i = 0;i<method.length;i++){ if(typeof method[i] !== 'string'){ throw new Error("xxx"); } this.method.push(method[i]); }}//public static methodInterface.ensureImplement = function(object){ for(var i = 0;i<arguments.length;i++){ var interface = arguments[i]; if(Interface.construction !== Interface){ throw new Error("xxx";) } for(var j = 0;j<ingerface.method.length;j++){ var method = interface.method[j]; if(!object[method] || typeof object[method] !==='function'){ throw new Error("xxx"); } } }}var testResultInstance = new Interface("testResultInstance",["getData","getResults"]);function testInterface = function(mapInstance){ Interface.ensureImplement(mapInstance,testResultInstance); mapInstance.getData(); mapInstance.getResults();}function Map(name){ this.name = name; this.getData = function(){}; this.getResults = function(){};}var mapInstance = new Map("test");testInterface(mapInstance);
三、繼承
/** * 繼承提供一些代碼複用的功能。但繼承照成兩個類間的強耦合 *///類式繼承function Person(name){ this.name = name;}function Design(name,book){ Person.call(this,name); this.book = book;}extend(Person,Desion);Design.prototype.getBooks = function(){ return this.book;}var d = new Design("tim","test");d.getBooks();d.name;function extend(superclass,subclass){ var F = function(){}; F.prototype = superclass.prototype; subclass.prototype = new F(); subclass.prototype.constructor = subclass subclass.superclass = superclass; if(superclass.prototype.constructor == Object.prototype.constructor){ superclass.prototype.constructor = superclass; }}/********************************************************************///原型繼承function clone(superclass){ var F = function(){}; F.prototype = superclass; return new F();}var Person = { name:"default", getName : function(){ return this.name; }};var Desion = clone(Person);Desion.books = ["寫給大家看的設計書"];Desion.getBooks = function(){ return this.books;}/********************************************************************///參元法var Mimin = function(){};Mimin.prototype = { name : 'default', getName : function(){ return this.name; }};function augment(receiveingClass,givingClass){ for(methodName in givingClass){ if(!receiveingClass[methodName]){ receiveingClass[methodName] = methodName; } }}