javascript 面向對象和繼承
阿新 • • 發佈:2018-01-22
color asc asdasdas java 代碼 round == ima 個人
我相信,當你讀完這篇100%原創文章時,javascript 面向對象和繼承輕松拿下不再是問題。
統一的html和css
<div id="app"></div> #app{ position: relative; width:500px; height:500px; background: #ccc; }
第一,面向對象是什麽,為什麽需要它。
這裏有另外一個詞,叫面向過程。先理解這個,比如我們需要用js寫出一個div自由降落的效果。我們自然而然是手動創建一個div,並且賦予它大小顏色位置做出運動。ok,這個問題不大,相信每個人都能搞定。
var app = document.getElementById(‘app‘); var div = document.createElement(‘div‘); var count = 0; div.style.position = ‘absolute‘; div.style.width = 20 + ‘px‘; div.style.height = 20 + ‘px‘; div.style.background = getColor(); app.appendChild(div); requestAnimationFrame(rectMove) function rectMove() { requestAnimationFrame(rectMove) div.style.top = (count++) + ‘px‘; if(div.offsetTop>480){ app.removeChild(div) } } function getColor(){ return ‘#‘+Math.floor(Math.random()*10)+Math.floor(Math.random()*10)+Math.floor(Math.random()*10); }
然而,第二天產品說要源源不斷的div(不同顏色,大小相同)自由降落,這時,我們腦袋就大了,難道要for循環幾千上萬個div?貌似不妥啊,小的做不到啊。。這就是面向過程的寫法和弊端。
這時候就需要面向對象的方法了。也就是用一個function,生成源源不斷的對象,這些對象大部分屬性方法都相同(比如大小相同),個別屬性方法特殊(比如顏色不同)。
var app = document.getElementById(‘app‘); var rects = []; var count = 0; function Rect1(width,height,x,backColor){ this.speed = -1;
this.x = x; this.width = width; this.height = height; this.backColor = backColor; } Rect1.prototype.move = function(){ this.nodeName.style.top = (this.nodeName.offsetTop - this.speed) + ‘px‘; }; function addChild(obj){ var ele = document.createElement(‘div‘); ele.style.position = ‘absolute‘;
ele.style.x = obj.x + ‘px‘; ele.style.width = obj.width + ‘px‘; ele.style.height = obj.height + ‘px‘; ele.style.background = obj.backColor; app.appendChild(ele); obj.nodeName = ele; //這個要註意 } requestAnimationFrame(rectMove) function rectMove() { requestAnimationFrame(rectMove) count++; if (count % 50 == 0) { var rect = new Rect1(20, 20,20, getColor()); addChild(rect); rects.push(rect) } for (var i = 0; i < rects.length; i++) { rects[i].move(); if (rects[i].nodeName.offsetTop > 480) { app.removeChild(rects[i].nodeName); rects.slice(item, 1) } } } function getColor(){ return ‘#‘+Math.floor(Math.random()*10)+Math.floor(Math.random()*10)+Math.floor(Math.random()*10); }
效果不錯吧,美滋滋,詳細細節請看阮大神這一章封裝。結論就是,面向對象最優的方法是把方法定義在prototype
對象上,屬性寫在構造函數上。
但是,第三天,親的產品又來了,說要再加一列div自由的降落。有了面向對象的我們,問題不大的,手起刀落寫下下面的代碼。
var app = document.getElementById(‘app‘); var rects = []; var rects2 = []; var count = 0; function Rect1(width,height,x,backColor){ this.speed = -1; this.x = x; this.width = width; this.height = height; this.backColor = backColor; } Rect1.prototype.move = function(){ this.nodeName.style.top = (this.nodeName.offsetTop - this.speed) + ‘px‘; }; //----- 新增重復的內容,第二列 function Rect2(width,height,x,backColor){ this.speed = -1; this.x = x; this.width = width; this.height = height; this.backColor = backColor; } Rect2.prototype.move = function(){ this.nodeName.style.top = (this.nodeName.offsetTop - this.speed) + ‘px‘; }; //----- 新增重復的內容 function addChild(obj){ var ele = document.createElement(‘div‘); ele.style.position = ‘absolute‘; ele.style.width = obj.width + ‘px‘; ele.style.height = obj.height + ‘px‘; ele.style.left = obj.x + ‘px‘; ele.style.background = obj.backColor; app.appendChild(ele); obj.nodeName = ele; } requestAnimationFrame(rectMove) function rectMove(){ requestAnimationFrame(rectMove) count++; if(count%50==0){ var rect = new Rect1(20,20,20,getColor()); addChild(rect); rects.push(rect) } rects.forEach(function(item,index,array){ item.move(); if(item.nodeName.offsetTop>480){ app.removeChild(item.nodeName); rects.slice(item,1) } }) if(count%80==0){ var rect = new Rect2(40,40,40,getColor()); addChild(rect); rects2.push(rect) } rects2.forEach(function(item,index,array){ item.move(); if(item.nodeName.offsetTop>480){ app.removeChild(item.nodeName); rects.slice(item,1) } }) } function getColor(){ return ‘#‘+Math.floor(Math.random()*10)+Math.floor(Math.random()*10)+Math.floor(Math.random()*10) }
效果如上,也還能見人。但是我們擔心啊,萬一萬惡的產品明天要第三列怎麽辦,把新增重復的內容再來一遍?不可能啊,這多愚蠢啊。此時,我們偉大的繼承上場了啊。
var app = document.getElementById(‘app‘); var rects = []; var rects2 = []; var count = 0;
//父類構造函數和方法 function Rect(width,height,x,backColor){ this.speed = -1; this.x = x; this.width = width; this.height = height; this.backColor = backColor; } Rect.prototype.move = function(){ this.nodeName.style.top = (this.nodeName.offsetTop - this.speed) + ‘px‘; };
//增加一個extend繼承函數(寄生組合繼承) function extend(Parent) { var Child = function(){ return Parent.apply(this, arguments); }; var F = function() {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.asdasdasdasd = Parent.prototype; return Child; } var Rect1 = extend(Rect); var Rect2 = extend(Rect);
// 這裏就可以繼續增加各種構造函數了,然後衍生,比如第三列增加一個border-radius屬性變成圓形。 function addChild(obj){ var ele = document.createElement(‘div‘); ele.style.position = ‘absolute‘; ele.style.width = obj.width + ‘px‘; ele.style.height = obj.height + ‘px‘; ele.style.left = obj.x + ‘px‘; ele.style.background = obj.backColor; app.appendChild(ele); obj.nodeName = ele; } requestAnimationFrame(rectMove) function rectMove(){ requestAnimationFrame(rectMove) count++; if(count%50==0){ var rect = new Rect1(20,20,20,getColor()); addChild(rect); rects.push(rect) } rects.forEach(function(item,index,array){ item.move(); if(item.nodeName.offsetTop>480){ app.removeChild(item.nodeName); rects.slice(item,1) } }) if(count%80==0){ var rect = new Rect2(40,40,40,getColor()); addChild(rect); rects2.push(rect) } rects2.forEach(function(item,index,array){ item.move(); if(item.nodeName.offsetTop>480){ app.removeChild(item.nodeName); rects.slice(item,1) } }) } function getColor(){ return ‘#‘+Math.floor(Math.random()*10)+Math.floor(Math.random()*10)+Math.floor(Math.random()*10) }
大家好好屢屢,
Rect,Rect1,Rect2三者的關系。一個爸爸兩個兒子。
全部代碼的地址 github。歡迎各位同學給右上角
。
javascript 面向對象和繼承