1. 程式人生 > >javascript 面向對象和繼承

javascript 面向對象和繼承

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 面向對象和繼承