JS面向對象(封裝,繼承)
阿新 • • 發佈:2017-07-02
通過 ray 混合 字母 顯示 彈出 pan rip http
在六月份找工作中,被問的最多的問題就是: js面向對象,繼承,封裝,原型鏈這些,你了解多少?
額,,,我怎麽回答呢, 只能說,了解一些,不多不少,哈哈哈哈,當然,這是玩笑話。
不過之前學過java,來理解這些還是很容易的。
所以趁著自己空閑的時間,理一理,,這些,,
一、封裝
1.原始方法
1 // 通過new關鍵字生成一個對象,然後根據javascript是動態語言的特性來添加屬性和方法,構造一個對象。其中this表示調用該方法的對象。 2 var obj = new Object(); 3 obj.name = ‘jessie‘; 4 obj.age = 22;5 obj.showName = function(){ 6 alert(this.name); 7 }; 8 obj.showAge = function(){ 9 alert(this.age); 10 } 11 obj.showName(); //jessie 12 obj.showAge(); // 22 13 // 這種方式的問題是如果需要多次創建對象,那麽需要重復代碼多次,不利於代碼的復用。
2.工廠模式
1 function createBlog(name, url) { 2 varobj = new Object(); 3 obj.name = name; 4 obj.url = url; 5 obj.sayName = function(){ 6 alert(this.name); 7 }; 8 obj.sayUrl = function() { 9 alert(this.url); 10 }; 11 return obj; 12 } 13 var blog1 = createBlog(‘jessie‘, ‘http://www.cnblogs.com/xiayu25/‘);14 var blog2 = createBlog(‘cuit‘, ‘http://www.cuit.edu.cn‘); 15 blog1.sayName(); // jessie 16 blog1.sayUrl(); // http://www.cnblogs.com/xiayu25/ 17 blog2.sayName(); // cuit 18 blog2.sayUrl(); // http://www.cuit.edu.cn 19 20 // 通過定義幾個函數的對象,解決了不同對象持有函數對象的私有屬性問題。 21 // 現在所有對象的方法都持有上面兩個函數的引用, 22 // 但這麽一來,對象的函數又和對象相互獨立了,這和面向對象中持有方法屬於與特定類的思想不符。 23 // 可以看到工廠模式的實現方法非常簡單,解決了創建多個相似對象的問題, 24 // 但是工廠模式卻無從識別對象的類型,因為全部都是Object,不像Date、Array等,因此出現了構造函數模式。
3.構造函數模式
1 function Blog(name, url){ 2 //var this=new Object(); //系統模擬創建對象 3 this.name = name; 4 this.url = url; 5 this.sayName = function(){ 6 alert(this.name); 7 }; 8 this.sayUrl = function(){ 9 alert(this.url); 10 }; 11 } 12 var blog1 = Blog(‘jessie‘, ‘http://www.cnblogs.com/xiayu25/‘); 13 var blog2 = Blog(‘cuit‘, ‘http://www.cuit.edu.cn‘); 14 blog1.sayName(); // jessie 15 blog1.sayUrl(); // http://www.cnblogs.com/xiayu25/ 16 blog2.sayName(); // cuit 17 blog2.sayUrl(); // http://www.cuit.edu.cn 18 // 這個例子與工廠模式中除了函數名不同以外,細心的童鞋應該發現許多不同之處: 19 // 函數名首寫字母為大寫(雖然標準沒有嚴格規定首寫字母為大寫,但按照慣例,構造函數的首寫字母用大寫) 20 // 沒有顯示的創建對象 21 // 直接將屬性和方法賦值給了this對象 22 // 沒有return語句 23 // 使用new創建對象 24 // 能夠識別對象(這正是構造函數模式勝於工廠模式的地方) 25 // 構造函數雖然好用,但也並非沒有缺點 26 // 構造函數的方式與工廠加工方式一樣,會為每個對象創建獨享的函數對象, 27 // 當然也可以將這些函數對象定義在構造函數外面,這樣又有了對象和方法相互獨立的問題
4.原型模式
1 function Blog() {} 2 Blog.prototype.name = ‘jessie‘; 3 Blog.prototype.url = ‘http://www.cnblogs.com/xiayu25/‘; 4 Blog.prototype.friend = [‘fr1‘, ‘fr2‘, ‘fr3‘, ‘fr4‘]; 5 Blog.prototype.alertInfo = function() { 6 alert(this.name + this.url + this.friend ); 7 }; 8 9 var blog1 = new Blog(), blog2 = new Blog(); 10 blog1.alertInfo(); // jessiehttp://www.cnblogs.com/xiayu25/fr1,fr2,fr3,fr4 11 blog2.alertInfo(); // jessiehttp://www.cnblogs.com/xiayu25/fr1,fr2,fr3,fr4 12 blog1.name = ‘test1‘; 13 blog1.url = ‘http://***.com‘; 14 blog1.friend.pop(); 15 blog2.name = ‘test2‘; 16 blog2.url = ‘http://+++.com‘; 17 blog1.alertInfo(); // test1http://***.comfr1,fr2,fr3 18 blog2.alertInfo(); // test2http://+++.comfr1,fr2,fr3 19 // 上面的代碼通過blog1向blog1的屬性friend添加元素時, 20 // blog2的friend屬性的元素也跟著受影響,原因是在於blog1和blog2對象的friend屬性引用的是同一個Array 21 // 對象,那麽改變這個Array對象,另一個引用Array對象的屬性自然也會受到影響
5.混合模式(原型模式 + 構造函數模式)
1 function Blog(name, url, friend) { 2 this.name = name; 3 this.url = url; 4 this.friend = friend; 5 } 6 7 Blog.prototype.alertInfo = function() { 8 alert(this.name + this.url + this.friend); 9 }; 10 11 var blog1 = new Blog(‘jessie‘, ‘http://www.cnblogs.com/xiayu25/‘, [‘fr1‘, ‘fr2‘, ‘fr3‘]), 12 blog2 = new Blog(‘cuit‘, ‘http://www.cuit.edu.cn‘, [‘a‘, ‘b‘]); 13 14 blog1.friend.pop(); 15 blog1.alertInfo(); // jessiehttp://www.cnblogs.com/xiayu25/fr1,fr2 16 blog2.alertInfo(); // cuithttp://www.cuit.edu.cna,b 17 18 //屬性私有後,改變各自的屬性不會影響別的對象。 19 // 同時,方法也是由各個對象共享的。在語義上,這符合了面向對象編程的要求。
6.動態原型模式
動態原型模式將所有信息封裝在了構造函數中,而通過構造函數中初始化原型(僅第一個對象實例化時初始化原型),這個可以通過判斷該方法是否有效而選擇是否需要初始化原型。
1 function Blog(name, url) { 2 this.name = name; 3 this.url = url; 4 5 if (typeof this.alertInfo != ‘function‘) { 6 // 這段代碼只執行了一次 7 alert(‘exe time‘); 8 Blog.prototype.alertInfo = function() { 9 alert(thia.name + this.url); 10 } 11 } 12 } 13 14 var blog1 = new Blog(‘jessie‘, ‘http://www.cnblogs.com/xiayu25/‘), 15 blog2 = new Blog(‘cuit‘, ‘http://www.cuit.edu.cn‘); 16 // 可以看到上面的例子中只彈出一次窗,‘exe time‘,即當blog1初始化時, 17 // 這樣做blog2就不在需要初始化原型,對於使用這種模式創建對象,可以算是perfect了。
二、繼承(主要是方法的繼承和屬性的繼承)
1 function person(name, sex){ 2 this.name=name; 3 this.sex=sex; 4 } 5 person.prototype.showName=function(){ 6 alert(this.name); 7 }; 8 person.prototype.showSex=function(){ 9 alert(this.sex); 10 }; 11 12 function worker(name,sex,job){ 13 person.call(this,name,sex);//構造函數偽裝 調用父級的構造函數--為了繼承屬性 14 this.job=job; 15 } 16 //原型鏈 通過原型來繼承父級的方法 17 for(attr in person.prototype){ 18 worker.prototype[attr]=person.prototype[attr]; 19 } 20 worker.prototype.showJob=function(){ 21 alert(this.job); 22 }; 23 24 var op=new person(‘blue‘,‘女‘); 25 var ow=new worker(‘blue‘,‘女‘,‘程序員‘); 26 op.showName(); //blue 27 op.showSex(); //女 28 ow.showName(); //blue 29 ow.showSex(); //女 30 ow.showJob(); //程序員 31 32 //繼承的好處:父類新加的功能,子類也具備該功能,子類新加的功能不會影響父類的功能
JS面向對象(封裝,繼承)