面向?qū)ο笈c面向過(guò)程的區(qū)別:
面向過(guò)程
面向?qū)ο?/strong>
*** √Tips:面向過(guò)程思想注重具體的步驟攒岛;面向?qū)ο笏枷胱⒅氐氖且粋€(gè)個(gè)對(duì)象酪术。面向?qū)ο笏枷肟梢允勾a結(jié)構(gòu)清晰妆毕、層次分明涝影,所以它可以幫助團(tuán)隊(duì)更好的分工協(xié)助句旱,提高開發(fā)效率抡驼。
面向?qū)ο蟮奶卣鳎褐饕ǚ庋b性鬼廓、繼承性和多態(tài)性
1、封裝性(表單生成器)
封裝指的是隱藏內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)致盟,只對(duì)外開放操作接口
(function(window) {
var FormBuilder =function(data) {
this.data = data;
};
window.FormBuilder =FormBuilder;
})(window);
上述代碼將表單生成器封裝成一個(gè)構(gòu)造函數(shù)碎税。其中最外層是一個(gè)自調(diào)用的匿名函數(shù),在調(diào)用時(shí)傳入的window對(duì)象用于控制FormBuilder庫(kù)的作用范圍馏锡,再通過(guò)window.FormBuilder =FormBuilder;將FormBuilder作為傳入對(duì)象的屬性雷蹂;
在匿名函數(shù)中定義的變量、函數(shù)都不會(huì)污染全局作用域杯道,體現(xiàn)了面向?qū)ο蟮姆庋b性匪煌。
2、繼承性
繼承是指一個(gè)對(duì)象繼承另一個(gè)對(duì)象的成員擎椰,從而在不改變另一個(gè)對(duì)象的前提下進(jìn)行擴(kuò)展
(1)、利用原型對(duì)象實(shí)現(xiàn)繼承
如果一個(gè)對(duì)象中本來(lái)沒(méi)有某個(gè)屬性或方法达舒,但可以從另一個(gè)對(duì)象中獲得即繼承
function Person(name) {
this.name = nam`e;
}
Person.prototype.sayHello =function () {
console.log('你好,我是' +this.name);
}
var p1 =new Person('Jim');
var p2 =new Person('Tom');
p1.sayHello();// 輸出結(jié)果:你好贯底,我是Jim
p2.sayHello();// 輸出結(jié)果:你好,我是 Tom
//p1胚想、p2本無(wú)sayHello()成員统屈,但在構(gòu)造函數(shù)Person的原型對(duì)象添加了sayHello()成員后,p1、p2也擁有了sayHello()成員思犁,即p1棉磨、p2對(duì)象繼承了原型對(duì)象中的成員环形。
(2)替換原型對(duì)象實(shí)現(xiàn)繼承
將構(gòu)造函數(shù)的原型對(duì)象替換成另一個(gè)對(duì)象A统抬,該構(gòu)造函數(shù)創(chuàng)建的對(duì)象就會(huì)繼承新的原型對(duì)象
function Person() {}// 構(gòu)造函數(shù)Person原本有一個(gè)原型對(duì)象prototype
Person.prototype = {// 將構(gòu)造函數(shù)的prototype屬性指向一個(gè)新的對(duì)象
sayHello:function () {// 在新的對(duì)象中定義一個(gè)sayHello()方法用于測(cè)試
console.log('你好,我是新對(duì)象');
}
}
var p =new Person();
p.sayHello();// 輸出結(jié)果:你好擎析,我是新對(duì)象
在基于構(gòu)造函數(shù)創(chuàng)建對(duì)象時(shí)棚瘟,代碼應(yīng)寫在替換原型對(duì)象之后
function Person() {}
Person.prototype.sayHello =function() {
console.log('原來(lái)的對(duì)象');
}
var p1 =new Person();
Person.prototype = {
sayHello:function(){
console.log('替換后的對(duì)象');
}
}
var p2 =new Person();
p1.sayHello();// 輸出結(jié)果:原來(lái)的對(duì)象
p2.sayHello();// 輸出結(jié)果:替換后的對(duì)象
//在通過(guò)替換原型對(duì)象的方式實(shí)現(xiàn)繼承時(shí)要注意代碼編寫的順序
(3)利用Object.create()實(shí)現(xiàn)繼承
var obj = {
sayHello:function(){
console.log('我是一個(gè)帶有sayHello方法的對(duì)象');
}
};
var newObj =Object.create(obj);
newObj.sayHello();// 輸出結(jié)果:我是一個(gè)帶有sayHello方法的對(duì)象
newObj.__proto__ ===obj;// 返回結(jié)果:true
//上述代碼實(shí)現(xiàn)了將obj對(duì)象作為newObj對(duì)象原型,newObj對(duì)象繼承了obj對(duì)象的sayHello()方法
(4)混入繼承
將一個(gè)對(duì)象的成員加入到另一個(gè)對(duì)象中,實(shí)現(xiàn)對(duì)象功能的擴(kuò)展
var o1 = {};
var o2 = {name:'Jim'};
o1.name =o2.name;// o1繼承o2的name屬性
console.log(o1.name);// 輸出結(jié)果:Jim
當(dāng)對(duì)象成員比較多時(shí),可以編寫一個(gè)函數(shù)專門實(shí)現(xiàn)對(duì)象成員的賦值舟陆,函數(shù)通常命名為mix(混合)或extend(擴(kuò)展)
// 編寫extend函數(shù)
function extend(o1, o2) {
for (var k in o2) {
o1[k] = o2[k];
}
}
// 測(cè)試extend函數(shù)
var o1 = {name:'Jim'};
var o2 = {age:16,gender:'male'};
extend(o1,o2);// 將o2的成員添加給o1
console.log(o1.name);// 輸出結(jié)果:Jim
console.log(o1.age);// 輸出結(jié)果:16
混入式繼承和原型繼承還可以組合在一起使用踱承,實(shí)現(xiàn)以對(duì)象的方式傳遞參數(shù),或以對(duì)象的方式擴(kuò)展原型對(duì)象成員
function Person(options) {
// 調(diào)用前面編寫的extend(),將傳入的options對(duì)象的成員添加到實(shí)例對(duì)象中
extend(this, options);
}
Person.fn =Person.prototype;// 將prototype屬性簡(jiǎn)化為fn方便代碼書寫
Person.fn.extend =function(obj) {
extend(this, obj);// 此處的this相當(dāng)于Peron.prototype
};
//以此之下五行代碼演示了以對(duì)象的方式擴(kuò)展原型對(duì)象的成員,當(dāng)需要為原型對(duì)象一次添加多個(gè)成員時(shí),使用這種方式會(huì)非常方便定庵,只需將這些成員保存到一個(gè)對(duì)象中,再調(diào)用extend()方法來(lái)繼承
Person.fn.extend({
sayHello:function() {
console.log('你好踪危,我是' + (this.name ||'無(wú)名'));
}
});
var p1 =new Person();
var p2 =new Person({name:'張三',age:16});//通過(guò)Person()構(gòu)造函數(shù)創(chuàng)建對(duì)象時(shí)傳入了對(duì)象形式的參數(shù)蔬浙,這種傳遞參數(shù)的方式相比傳遞多個(gè)參數(shù)更加靈活
p1.sayHello();// 輸出結(jié)果:你好畴博,我是無(wú)名
p2.sayHello();// 輸出結(jié)果:你好俱病,我是張三
3溢吻、多態(tài)性
多態(tài)指的是同一個(gè)操作作用于不同的對(duì)象阅畴,會(huì)產(chǎn)生不同的執(zhí)行結(jié)果题翰。JavaScript中一個(gè)變量可以存儲(chǔ)任意類型的數(shù)據(jù)就是多態(tài)性的體現(xiàn)恶阴。其中如數(shù)字焦匈、數(shù)組血公、函數(shù)都具有toString()方法,當(dāng)使用不同的對(duì)象調(diào)用該方法時(shí)缓熟,執(zhí)行不同的結(jié)果累魔。
var obj =123;
console.log(obj.toString());// 輸出結(jié)果:123
obj = [1,2,3];
console.log(obj.toString());// 輸出結(jié)果:1,2,3
obj =function() {};
console.log(obj.toString());// 輸出結(jié)果:function () {}
//面向?qū)ο笾校鄳B(tài)性的實(shí)現(xiàn)基本離不開繼承够滑。因?yàn)楫?dāng)多個(gè)對(duì)象繼承了同一個(gè)對(duì)象后垦写,就獲得了相同的方法,然而根據(jù)每個(gè)對(duì)象的需求來(lái)改變同名方法的執(zhí)行結(jié)果彰触。
ps:例子程序
包含了一些面向?qū)ο髮傩缘奶匦?/p>
var elements = [
{tag: 'input', text: '姓名:', attr: {type: 'text', name: 'user'}},//將姓名:<input type="text" name="user">轉(zhuǎn)化為對(duì)象
{tag: 'input', text: '性別:', attr: {type: 'radio', name: 'gender'}, option: {m: '男', w: '女'}},
{tag: 'input', text: '愛好:', attr: {type: 'checkbox', name: 'hobby[]'}, option: {swimming: '游泳', reading: '讀書', running: '跑步'}},
{tag: 'select', text:'住址:', attr: {name: 'area'}, option: {'': '--請(qǐng)選擇--', bj: '北京', sh: '上海', sz: '深圳'}},
{tag: 'textarea', text: '自我介紹:', attr: {name: 'introduce', cols:'50', rows: '5'}},
{tag: 'input', attr: {type: 'submit', value: '確定'}}
];
//上述代碼中梯投,每個(gè)表單項(xiàng)都具有tag、text况毅、attr和option4個(gè)屬性分蓖,表示它們具有相同的特征。而每個(gè)表單項(xiàng)的標(biāo)簽名尔许、提示文本么鹤、屬性值是不同的,這表示每個(gè)對(duì)象都有不同之處
document.getElementById('form').innerHTML = new FormBuilder(elements).create();
//封裝表單生成器味廊,前面有詳解
(function(window) {
var FormBuilder = function(data) {
this.data = data;
};
//接下來(lái)的所有代碼都是為了實(shí)現(xiàn)表單的自動(dòng)生成
//編寫create()方法
FormBuilder.prototype.create = function() {
var html = '';
for (var k in this.data) {//this.data表示傳入的elements數(shù)組
var item = {tag: '', text: '', attr: {}, option: null};
for (var n in this.data[k]) {//接下來(lái)7行代碼遍歷整個(gè)數(shù)組
item[n] = this.data[k][n];
}
html += builder.toHTML(item);
}
return '<table>' + html + '</table>';
};//上述11行代碼實(shí)現(xiàn)了表單的自動(dòng)的生成
//編寫builder對(duì)象蒸甜,builder是封裝在匿名函數(shù)內(nèi)部的對(duì)象棠耕,專門用于對(duì)每一種表單項(xiàng)進(jìn)行生成
var builder = {
toHTML: function(obj) {
var html = this.item[obj.tag](this.attr(obj.attr), obj.option);
return '<tr><th>' + obj.text + '</th><td>' + html + '</td></tr>';
},//上述3行代碼中,“this.item[obj.tag]()”用于根據(jù)obj.tag的值來(lái)調(diào)用item對(duì)象中的方法柠新。當(dāng)obj.tag的值為input時(shí)窍荧,就表示調(diào)用builder.item.input()方法
//接下來(lái)編寫attr()方法,實(shí)現(xiàn)將“{type:'text',name:'user'}”形式的對(duì)象轉(zhuǎn)換為“type="text" name="user"”形式的HTML字符串
attr: function(attr) {
var html = '';
for(var k in attr) {
html += k + '="' + attr[k] + '" ';
}
return html;
},
//編寫item對(duì)象
item: {
input: function(attr, option) {
var html = '';
if (option === null) {//通過(guò)判斷option是否為null登颓,來(lái)區(qū)分單個(gè)控件和組合控件
html += '<input ' + attr + '>';
} else {
for (var k in option) {
html += '<label><input ' + attr + 'value="' + k + '"' + '>' + option[k] + '</label>';//在生成組合控件時(shí)使用label標(biāo)簽包裹input標(biāo)簽搅荞,這樣可以擴(kuò)大選擇范圍,當(dāng)單擊提示文本時(shí)框咙,相應(yīng)的表單控件就會(huì)被選中
}
}
return html;
},
select: function(attr, option) {
var html = '';
for (var k in option) {
html += '<option value="' + k + '">' + option[k] + '</option>';
}
return '<select ' + attr +'>' + html + '</select>';
},
//編寫item對(duì)象中的textarea()方法
textarea: function(attr) {
return '<textarea ' + attr + '></textarea>';
}
}
};
window.FormBuilder = FormBuilder;
})(window);
- 文/潘曉璐 我一進(jìn)店門愉粤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人拿撩,你說(shuō)我怎么就攤上這事衣厘。” “怎么了压恒?”我有些...
- 文/不壞的土叔 我叫張陵影暴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我探赫,道長(zhǎng)型宙,這世上最難降的妖魔是什么? 我笑而不...
- 正文 為了忘掉前任伦吠,我火速辦了婚禮妆兑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘讨勤。我一直安慰自己箭跳,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開白布潭千。 她就那樣靜靜地躺著谱姓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刨晴。 梳的紋絲不亂的頭發(fā)上屉来,一...
- 那天路翻,我揣著相機(jī)與錄音,去河邊找鬼茄靠。 笑死茂契,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的慨绳。 我是一名探鬼主播掉冶,決...
- 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼脐雪!你這毒婦竟也來(lái)了厌小?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤战秋,失蹤者是張志新(化名)和其女友劉穎璧亚,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脂信,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡癣蟋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狰闪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疯搅。...
- 正文 年R本政府宣布,位于F島的核電站规阀,受9級(jí)特大地震影響恒序,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谁撼,卻給世界環(huán)境...
- 文/蒙蒙 一歧胁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厉碟,春花似錦喊巍、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至款咖,卻和暖如春何暮,著一層夾襖步出監(jiān)牢的瞬間奄喂,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓坏逢,卻偏偏與公主長(zhǎng)得像域帐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子是整,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- ??面向?qū)ο螅∣bject-Oriented贰盗,OO)的語(yǔ)言有一個(gè)標(biāo)志许饿,那就是它們都有類的概念,而通過(guò)類可以創(chuàng)建任意...
- 一舵盈、 JS面向?qū)ο缶幊?1陋率、 面向?qū)ο蠼榻B 什么是對(duì)象? Everything is object (萬(wàn)物皆對(duì)象)...
- 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對(duì)象屬性創(chuàng)建對(duì)象繼承 什么是面向?qū)ο?面向?qū)ο?..
- 基本概念 語(yǔ)法區(qū)分大小寫標(biāo)識(shí)符注釋嚴(yán)格模式語(yǔ)句 關(guān)鍵字和保留字 變量 數(shù)據(jù)類型typeof 操作符Undefine...