帶你了解面向?qū)ο蠛兔嫦蜻^程的區(qū)別
講面向?qū)ο罅常碗x不開講一講面向過程。
面向?qū)ο蠛兔嫦蜻^程是現(xiàn)在編程的主要拌倍。
一赂鲤、面向過程簡述
面向過程:顧名思義噪径,當你處理一個事情的時候,它會按照過程逐步進行数初,著重于步驟找爱。
比如求一個循環(huán)數(shù)的和:
var num = 0;
for(var i = 0;i < 5;i++){
sum += i;
}
這樣解決問題的代碼簡潔明了,關(guān)注的是解決問題的步驟即可泡孩,但是如果僅限于求和要求面向過程就足夠了缴允,因為邏輯簡單,不需要太過復(fù)雜的邏輯架構(gòu)去幫你理清解題思路珍德。
這是一個簡單的面向過程的例子,如果要再執(zhí)行一個循環(huán)六次的求和矗漾。就會如下代碼:
var num = 0;
for(var i = 0;i < 5;i++){
sum += i;
}
for(var i =0;i < 6;i++){
sum += i;
}
那如果還要繼續(xù)執(zhí)行呢锈候?碰到了結(jié)構(gòu)復(fù)雜的程序,這個時候就發(fā)現(xiàn)重復(fù)的代碼過多敞贡,造成代碼冗余泵琳,而且如果寫多了,不利于思路條例誊役。
二获列、面向?qū)ο蠛喪?br>
1.面向?qū)ο螅好嫦驅(qū)ο蟮闹攸c在于對象,先創(chuàng)建一個對象然后借助對象的值屬性和方法來存儲數(shù)據(jù)以及解決問題蛔垢。
如同樣求一個循環(huán)數(shù)的和的代碼:
function CreateAddtion (num){
this.sum = 0; //求和最終結(jié)果
this.count = num; //循環(huán)次數(shù)
this.addtion = function (){
for(var i = 0;i < this.count;i++){
this.sum += i;
}
return this.sum;
}
}
var add1 =new CreateAddtion(5);//5次和
var add2 = new CreateAddtion(6);//6次和
console.log(add1.addtion());
console.log(add2.addtion());
面向?qū)ο蟮奶卣骶驮谟诨骱ⅲ岛徒鉀Q方案都交給對象存儲和處理,要想調(diào)用對象里的方法鹏漆,必須先聲明對象巩梢。當然在這個例子里,并不能突出面向?qū)ο蟮暮锰帯?br> 下面舉個例子艺玲,最經(jīng)常被拿來當教案的鴨子的故事為背景括蝠。
要求:模擬一個游戲,會出現(xiàn)多只鴨子饭聚,并且鴨子會游泳會叫忌警。鴨子分紅頭和綠頭鴨子。
面向過程:
//一下都是偽代碼,
//假設(shè)要2只鴨子
var yazi = function(){
CreateYaZi();//創(chuàng)建鴨子
Swin(); //游泳
guagua() //呱呱叫
red(); //在此處寫red();或者green()來修改紅頭鴨子和綠頭鴨子
}
//因為是兩只秒梳,以上代碼執(zhí)行for循環(huán)或者寫兩遍法绵。
面向?qū)ο?
//以下是偽代碼
function CreateYaZi (color){
this.color = color; //紅頭鴨子綠頭鴨子
this.Swin = function (){
//游泳
}
this.Guagua = function (){
//叫
}
}
var yazi1 = new CreateYaZi(red);
var yazi2 = new CreateYaZi(green);
在這個例子里,區(qū)別最大的在于紅綠頭鴨子端幼,如果用面向過程礼烈,每創(chuàng)建一個鴨子都需要程序員手動修改,但是如果用對象婆跑,直接根據(jù)傳遞的形參來給鴨子頭顏色賦值此熬,減少了代碼量,并且清晰了邏輯武契,如果還覺得這樣區(qū)別不大洁桌,可以增加要求叽赊,比如鴨子分為橡皮鴨佩微,紅綠頭鴨子枷遂,這兩種鴨子叫聲不一樣祥绞,橡皮鴨吱吱吱叫姓惑,紅綠頭鴨子嘎嘎嘎叫操灿,
這個時候程序員如果用面向過程的思想搀庶,就會去創(chuàng)建叫法不同的方法拐纱,分別給創(chuàng)建的鴨子賦值,而面向?qū)ο蟾缇螅恍枰膶ο蟮膶傩越占埽鶕?jù)屬性執(zhí)行相應(yīng)的函數(shù)即可。
由此可見的咆蒿,在大量的邏輯思維和需要后期維護大量需求的背景下东抹,使用面向?qū)ο笫谴蟠蠓奖懔顺绦騿T理清思路,并且減輕代碼量的沃测。
當然我個人覺得我舉這個例子也不大好缭黔,如果沒怎么理解,可以參考其他博客蒂破。
四馏谨、JS是基于對象的語言
1.什么樣的編程是面向?qū)ο蟮木幊蹋?br>
(1)面向?qū)ο缶幊袒谑褂妹嫦驅(qū)ο笳Z言編程。
(2)具備的概念:類附迷、對象田巴。
(3)具備的特征:封裝、多態(tài)挟秤、繼承
(4)在創(chuàng)建對象時必須通過類創(chuàng)建壹哺。
批注:類是具有相同屬性和方法的集合,對象是類的實例化艘刚。
批注:封裝是把具體實現(xiàn)功能的代碼封裝成一個塊(方法)管宵,需要使用時調(diào)用方法即可。
批注:繼承是類和類之間一旦聲明了繼承關(guān)系攀甚,比如A繼承B也就是說A是B創(chuàng)建的子類箩朴。A子B父。子類必須繼承父類的所有方法秋度,并且可以選擇重寫父類的方法炸庞。
批注:多態(tài)是多個對象根據(jù)同一個類創(chuàng)建,同一個屬性值可能不同荚斯,同一個方法執(zhí)行的結(jié)果也可能不同埠居。
2.JS可以用面向?qū)ο缶幊虇幔?br>
可以查牌,但是并不完整。
(1)JS是基于對象的語言滥壕,它又具有面向過程語言的特點纸颜,又具有面向?qū)ο缶幊陶Z言的特點,但是雙方都不完善绎橘。
(2)JS沒有類和借口的概念胁孙,無法進行真正意義上通過類創(chuàng)建對象。
(3)JS可以用函數(shù)塊模擬面向?qū)ο筮^程的通過類創(chuàng)建對象称鳞,也就是說通過new類函數(shù)涮较,來創(chuàng)建對象,類函數(shù)中有相應(yīng)的屬性賦值和方法執(zhí)行冈止。
教你如何用JS創(chuàng)建對象
JS沒有類和接口的概念法希,只有方法,如果想用JS實現(xiàn)面向?qū)ο缶幊贪腥常梢杂梅椒M創(chuàng)建類的過程。
方法1:直接聲明創(chuàng)建實例
var Yazi ={
name : '鴨子'毛肋,
color : '紅頭'怨咪,
swin : function(){//我會游泳},
guaGua : function(){//我會呱呱叫}润匙,
};
console.log(Yazi.name);
console.log(Yazi.color);
Yazi.swin();
Yazi.guaGua();
方法2:調(diào)用工廠函數(shù)創(chuàng)建實例
function createYaZi (color){
//創(chuàng)建一個對象
var yazi = new Object();
//或
//var yazi = {};
yazi.name = '鴨子';
yazi.color = color;
yazi.swin = function () {
//我會游泳
}
yazi.guaGua = function () {
//我會呱呱叫
}
return yazi;
}
var yazi1 =createYaZi('red');
console.log(yazi1);
console.log(yazi1 instanceof Object);
var yazi2 = createYaZi('green');
console.log(yazi2);
console.log(yazi1);
結(jié)果:
或者
方法3:構(gòu)造函數(shù)(函數(shù)名的首字母大寫)
function CreateYaZi (color){
this.name = '鴨子';
this.color = color;
this.swin = function () {
//我會游泳
}
this.guaGua = function () {
//我會呱呱叫
}
}
var yazi1 =new CreateYaZi('red');
console.log(yazi1);
console.log(yazi1 instanceof Object);
var yazi2 =new CreateYaZi('green');
console.log(yazi2);
console.log(yazi1);
結(jié)果:
方法4:通過原型創(chuàng)建方法(包含動態(tài)創(chuàng)建原型)
優(yōu)點:可以把共有的數(shù)據(jù)和方法統(tǒng)一存到 原型中诗眨,達到節(jié)約內(nèi)存的目的。
function CreateYaZi (color){
CreateYaZi.prototype.name = '鴨子'; //共有的數(shù)據(jù)
this.color = color;
this.swin = function () {
//我會游泳
}
//這里是動態(tài)原型創(chuàng)建孕讳,如過原型中的方法和屬性已經(jīng)存在匠楚,就不會再對
//其進行添加
if (typeof(CreateYaZi.guaGua) != 'function') {
CreateYaZi.prototype.guaGua=function () {
//我會呱呱叫
}
}
}
var yazi1 =new CreateYaZi('red');
console.log(yazi1);
console.log(yazi1 instanceof Object);
var yazi2 =new CreateYaZi('green');
console.log(yazi2);
console.log(yazi1);
結(jié)果:
放在原型中的共有數(shù)據(jù)和方法都在實例化的對象的proto里,這個屬性最好不要修改厂财。
JS訪問對象屬性
訪問:
(1)對象名.屬性名 例如:yazi.name
(2)對象名[‘屬性名’] 例如 :yazi['name'] //這個方法不要有空格芋簿,否則可能影響檢索屬性的精準。
刪除:
delete yazi.name;
循環(huán)遍歷訪問對象
(1)for..in(遍歷下標)
for (var item in yazi) {
if ((typeof yazi[item]) != 'function') {
//判斷鴨子獲取到的是否是方法璃饱,不是的話執(zhí)行輸出屬性值与斤。
console.log(yazi[item]);
}
}
(2)for..of(遍歷數(shù)據(jù))
for (var item of yazi) {
if ((typeof yazi[item]) != 'function') {
//判斷鴨子獲取到的是否是方法,不是的話執(zhí)行輸出屬性值荚恶。
console.log(yazi[item]);
}
}
失敗的原因是因為對象只能通過下標和屬性名拿值撩穿。
刪除