javascript
JavaScript从入门到放弃 - ES6中的对象和类
重點(diǎn)講解Tab欄切換、增、刪、改
- 1. 面向過(guò)程與面向?qū)ο?/li>
- 2.ES6 中的對(duì)象與類(lèi)
- 2.1 對(duì)象
- 2.2 類(lèi)
- 2.2.1 創(chuàng)建類(lèi)
- 2.2.1.1 語(yǔ)法
- 2.2.1.2 實(shí)例
- 2.2.2 類(lèi)創(chuàng)建添加屬性和方法
- 2.2.3 類(lèi)的繼承
- 2.2.3.1 語(yǔ)法
- 2.2.3.2 實(shí)例
- 2.2.3.3 注意事項(xiàng)
- 3. 面向?qū)ο蟀咐?/li>
- 3.1 面向?qū)ο蟀鎡ab欄切換
- 3.1.1 案例準(zhǔn)備
- 3.1.1.1抽象對(duì)象:Tab對(duì)象
- 3.1.1.2 創(chuàng)建(Tab)類(lèi)
- 3.1.1.3 獲取元素并調(diào)用初始化函數(shù)綁定事件
- 3.1.2 切換功能實(shí)現(xiàn)
- 3.1.3 添加功能的實(shí)現(xiàn)
- 3.1.4 刪除功能模塊
- 3.1.5 編輯功能模塊
1. 面向過(guò)程與面向?qū)ο?/h1>
- 面向過(guò)程:就是分析出解決問(wèn)題所需要的步驟,然后用函數(shù)把這些步驟一步一步實(shí)現(xiàn),使用的時(shí)候再一個(gè)一個(gè)的依次調(diào)用;
- 面向?qū)ο?/strong>:是把事務(wù)分解成為一個(gè)個(gè)對(duì)象,然后由對(duì)象之間分工與合作。
面向?qū)ο蟮乃季S特點(diǎn):
面向?qū)ο缶幊淌紫瓤紤]的是有哪些對(duì)象,按照面向?qū)ο蟮乃季S特點(diǎn),不斷創(chuàng)建對(duì)象、使用對(duì)象、指揮對(duì)象做事情。
面向過(guò)程與面向?qū)ο髮?duì)比:
| 優(yōu)點(diǎn) | 性能比面向?qū)ο蟾?#xff0c;適合跟硬件聯(lián)系很緊密的東西,例如單片機(jī)就采用的面向過(guò)程編程。 | 易維護(hù)、易復(fù)用、易擴(kuò)展,由于面向?qū)ο笥蟹庋b、繼承、多態(tài)性的特性,可以設(shè)計(jì)出低耦合的系統(tǒng),使系統(tǒng) 更加靈活、更加易于維護(hù) |
| 缺點(diǎn) | 不易維護(hù)、不易復(fù)用、不易擴(kuò)展 | 性能比面向過(guò)程低 |
2.ES6 中的對(duì)象與類(lèi)
2.1 對(duì)象
- 現(xiàn)實(shí)生活中
萬(wàn)物皆對(duì)象。對(duì)象是一個(gè)具體的事物,看得見(jiàn)、摸得著的實(shí)物; - 在JavaScript中
對(duì)象是一組無(wú)序的相關(guān)屬性和方法的集合,所有的事物都是對(duì)象,如字符串、數(shù)值、數(shù)組、函數(shù)等
對(duì)象:由屬性和方法組成:是一個(gè)無(wú)序鍵值對(duì)的集合,指的是一個(gè)具體的事物。
- 屬性:即事物的特征,在對(duì)象中用屬性來(lái)表示(常用名詞);
- 方法:即事物的行為,在對(duì)象中用方法來(lái)表示(常用動(dòng)詞);
以下代碼是對(duì)對(duì)象的復(fù)習(xí):
//字面量創(chuàng)建對(duì)象 var ldh = {name: '劉德華',age: 18 } console.log(ldh);//構(gòu)造函數(shù)創(chuàng)建對(duì)象function Star(name, age) {this.name = name;this.age = age;} var ldh = new Star('劉德華', 18)//實(shí)例化對(duì)象 console.log(ldh);2.2 類(lèi)
在 ES6 中新增加了類(lèi)的概念,可使用 class 關(guān)鍵字聲明一個(gè)類(lèi),之后以這個(gè)類(lèi)來(lái)實(shí)例化對(duì)象。類(lèi)抽象了對(duì)象的公共部分,它泛指某一大類(lèi)(class)對(duì)象特指某一個(gè),通過(guò)類(lèi)實(shí)例化一個(gè)具體的對(duì)象。
類(lèi) class:泛指某一大類(lèi);
對(duì)象:特指某一事物(通過(guò)類(lèi)實(shí)例化產(chǎn)生的)。
2.2.1 創(chuàng)建類(lèi)
2.2.1.1 語(yǔ)法
步驟1: 使用class關(guān)鍵字
class name {// class body }步驟2:使用定義的類(lèi)創(chuàng)建實(shí)例 ,new關(guān)鍵字
var xx = new name();2.2.1.2 實(shí)例
1.)創(chuàng)建類(lèi) class:創(chuàng)建一個(gè)明星類(lèi)
class Star {// 類(lèi)的共有屬性放到 constructor 里面constructor(name, age) {this.name = name;this.age = age;}}2.) 利用類(lèi)創(chuàng)建對(duì)象 new
var ldh = new Star('劉德華', 18);console.log(ldh);以上代碼運(yùn)行結(jié)果::
我們可以看出和使用構(gòu)造函數(shù)的結(jié)果是一樣。
2.2.2 類(lèi)創(chuàng)建添加屬性和方法
1). 創(chuàng)建類(lèi) class 創(chuàng)建一個(gè)類(lèi)
class Star {// 類(lèi)的共有屬性放到constructor里面,constructor是構(gòu)造器或者構(gòu)造函數(shù)constructor(uname, age) {this.uname = uname;this.age = age;}//------------------------------------------->注意,方法與方法之間不需要添加逗號(hào)sing(song) {console.log(this.uname + '唱' + song);} }所有的 class 類(lèi)里面不需要加 function
2). 利用類(lèi)創(chuàng)建對(duì)象 new
var ldh = new Star('劉德華', 18); console.log(ldh); // Star {uname: "劉德華", age: 18} ldh.sing('冰雨'); // 劉德華唱冰雨
注意:
- 通過(guò)class 關(guān)鍵字創(chuàng)建類(lèi), 類(lèi)名我們還是習(xí)慣性定義首字母大寫(xiě)
- 類(lèi)里面有個(gè)constructor 函數(shù),可以接受傳遞過(guò)來(lái)的參數(shù),同時(shí)返回實(shí)例對(duì)象
- constructor 函數(shù) 只要 new 生成實(shí)例時(shí),就會(huì)自動(dòng)調(diào)用這個(gè)函數(shù), 如果我們不寫(xiě)這個(gè)函數(shù),類(lèi)也會(huì)自動(dòng)生成這個(gè)函數(shù)
- 多個(gè)函數(shù)方法之間不需要添加逗號(hào)分隔
- 生成實(shí)例 new 不能省略
語(yǔ)法規(guī)范,
- 創(chuàng)建類(lèi)
類(lèi)名后面不要加小括號(hào),而是直接跟一個(gè){}; - 生成實(shí)例
類(lèi)名后面加小括號(hào), 構(gòu)造函數(shù)不需要加function;
并且,多個(gè)函數(shù)和方法之間,不能添加標(biāo)點(diǎn)符號(hào)做分隔。
3)在類(lèi)中添加方法:直接把函數(shù)或者方法寫(xiě)到類(lèi)里面
class Star {// 類(lèi)的共有屬性放到 constructor 里面 constructor是 構(gòu)造器或者構(gòu)造函數(shù)constructor(uname, age) {this.uname = uname;this.age = age;}//------------------------------------------->注意,方法與方法之間不需要添加逗號(hào)sing(song) {console.log(this.uname + '唱' + song);} } // 2. 利用類(lèi)創(chuàng)建對(duì)象 new var ldh = new Star('劉德華', 18); console.log(ldh); // Star {uname: "劉德華", age: 18} ldh.sing('冰雨'); // 劉德華唱冰雨2.2.3 類(lèi)的繼承
在程序中,子類(lèi)可以繼承父類(lèi)的一些屬性和方法
2.2.3.1 語(yǔ)法
// 父類(lèi) class Father{ } // 子類(lèi)繼承父類(lèi) class Son extends Father { }2.2.3.2 實(shí)例
class Father {constructor(surname) {this.surname= surname;}say() {console.log('你的姓是' + this.surname);} } class Son extends Father{ // 這樣子類(lèi)就繼承了父類(lèi)的屬性和方法 } var damao= new Son('劉'); damao.say(); //結(jié)果為 你的姓是劉- 子類(lèi)使用super關(guān)鍵字訪問(wèn)父類(lèi)的方法
繼承的關(guān)鍵字extends
super:調(diào)用父類(lèi)中的構(gòu)造函數(shù)或普通函數(shù),可以把constructor()里的數(shù)據(jù)傳遞給父類(lèi)。
2.2.3.3 注意事項(xiàng)
注意:
-
繼承中,如果實(shí)例化子類(lèi)輸出一個(gè)方法,先看子類(lèi)本身有沒(méi)有這個(gè)方法,如果有就先執(zhí)行子類(lèi)的;
-
繼承中,如果子類(lèi)里面沒(méi)有,就去查找父類(lèi)有沒(méi)有這個(gè)方法,如果有,就執(zhí)行父類(lèi)的這個(gè)方法(就近原則);
-
如果子類(lèi)想要繼承父類(lèi)的方法,同時(shí)在自己內(nèi)部擴(kuò)展自己的方法,利用super 調(diào)用父類(lèi)的構(gòu)造函數(shù),super 必須在子類(lèi)this之前調(diào)用。
-
時(shí)刻注意this的指向問(wèn)題,類(lèi)里面的共有的屬性和方法一定要加this使用.。
- constructor中的this指向的是new出來(lái)的實(shí)例對(duì)象
- 自定義的方法,一般也指向的new出來(lái)的實(shí)例對(duì)象
- 綁定事件之后this指向的就是觸發(fā)事件的事件源
-
在 ES6 中類(lèi)沒(méi)有變量提升,所以必須先定義類(lèi),才能通過(guò)類(lèi)實(shí)例化對(duì)象:
- 類(lèi)里面的共有的屬性和方法一定要加this使用;
- this 問(wèn)題
- constructor 里面的this,指向的是創(chuàng)建的實(shí)例對(duì)象;
- 方法中的this指向不清楚,只有在調(diào)用的時(shí)候才清楚,this指向調(diào)用者。
3. 面向?qū)ο蟀咐?/h1>
3.1 面向?qū)ο蟀鎡ab欄切換
功能需求:
- 點(diǎn)擊 tab欄,可以切換效果;
- 點(diǎn)擊 + 號(hào), 可以添加 tab 項(xiàng)和內(nèi)容項(xiàng);
- 點(diǎn)擊 x 號(hào), 可以刪除當(dāng)前的tab項(xiàng)和內(nèi)容項(xiàng);
- 雙擊 tab項(xiàng) 文字或內(nèi)容項(xiàng)文字,可以修改里面的文字內(nèi)容。
面向?qū)ο缶幊趟悸?#xff1a;
3.1.1 案例準(zhǔn)備
3.1.1.1抽象對(duì)象:Tab對(duì)象
該對(duì)象具有:
3.1.1.2 創(chuàng)建(Tab)類(lèi)
class Tab {constructor(){}// 1、切換功能toggle(){}// 2、添加功能addTab(){}// 3、刪除功能removeTab(){}// 4、修改功能editTab(){} };3.1.1.3 獲取元素并調(diào)用初始化函數(shù)綁定事件
class Tab {constructor(id){// 獲取元素this.main=document.querySelector(id);this.lis=this.main.querySelectorAll('li');this.sections=this.main.querySelectorAll('section');}init(){// init 初始化,讓頁(yè)面加載時(shí)相關(guān)的元素綁定事件for (var i=0; i< this.lis.length;i++){this.lis[i].index=i;this.lis[i].onclick=function(){}}}// 1、切換功能toggleTab(){}// 2、添加功能addTab(){}// 3、刪除功能removeTab(){}// 4、修改功能editTab(){} }; new Tab('#tab');3.1.2 切換功能實(shí)現(xiàn)
var that; class Tab {constructor(id) {that = this;// 獲取元素this.main = document.querySelector(id);this.lis = this.main.querySelectorAll('li');this.sections = this.main.querySelectorAll('section');this.init();}init() {// init 初始化,讓頁(yè)面加載時(shí)相關(guān)的元素綁定事件for (var i = 0; i < this.lis.length; i++) {this.lis[i].index = i;this.lis[i].onclick = this.toggleTab;}}// 1、切換功能toggleTab() {// console.log(this.index);that.clearClass();this.className = 'liactive';that.sections[this.index].className = 'conactive';}clearClass() {for (var i = 0; i < this.lis.length; i++) {this.lis[i].className = '';this.sections[i].className = '';}}// 2、添加功能addTab() {}// 3、刪除功能removeTab() {}// 4、修改功能editTab() {} }; new Tab('#tab');聲明了一個(gè)全局變量that,在constructor對(duì)其進(jìn)行賦值,以解決this指向(lis)問(wèn)題。
書(shū)寫(xiě)了一個(gè)利用循環(huán)清除樣式的clearClass方法。
3.1.3 添加功能的實(shí)現(xiàn)
功能分析:
第一步:創(chuàng)建新的選項(xiàng)卡li和新的內(nèi)容section;
- 傳統(tǒng)的做法:動(dòng)態(tài)創(chuàng)建元素createElement。但是元素里內(nèi)容較多,需要innerHTML賦值,再appendChild追加到父元素;
- 高級(jí)的做法:利用insertAdjacentHTML()可以直接把字符串格式元素添加到父元素中。
點(diǎn)擊前往 :insertAdjacentHTML方法官方使用說(shuō)明
appendChild不支持追加字符串的子元素;
insertAdjacentHTML支持追加字符串的元素。
注:后添加的li和section,不能在頁(yè)面加載時(shí)獲取 ,因此會(huì)出現(xiàn)后添加的li和section沒(méi)有切換效果,此時(shí)就將獲取li元素和section元素的放到函數(shù)updateNode里,在點(diǎn)擊+號(hào)時(shí),重新調(diào)用此函數(shù)獲取元素并綁定onclick事件,代碼如下:
var that; class Tab {constructor(id) {that = this;// 獲取元素this.main = document.querySelector(id);this.add = this.main.querySelector('.tabadd');// 獲取 li 的父元素this.ul = this.main.querySelector('.fisrstnav ul:first-child');// 獲取 section的父元素this.fsection = this.main.querySelector('.tabscon');this.init();}init() {this.updateNode();// init 初始化,讓頁(yè)面加載時(shí)相關(guān)的元素綁定事件this.add.onclick = this.addTab;for (var i = 0; i < this.lis.length; i++) {this.lis[i].index = i;this.lis[i].onclick = this.toggleTab;}}// 獲取所有的小li 和 sectionupdateNode() {this.lis = this.main.querySelectorAll('li');this.sections = this.main.querySelectorAll('section');}// 1、切換功能toggleTab() {// console.log(this.index);that.clearClass();this.className = 'liactive';that.sections[this.index].className = 'conactive';}clearClass() {for (var i = 0; i < this.lis.length; i++) {this.lis[i].className = '';this.sections[i].className = '';}}// 2、添加功能addTab() {that.clearClass();// 1、創(chuàng)建li元素和section元素;var random = Math.random();var li = '<li class="liactive"><span>新標(biāo)簽頁(yè)</span><span class="iconfont icon-guanbi"></span></li>';var section = '<section class="conactive">測(cè)試' + random + '</section>';// 2、把這兩個(gè)元素追加到對(duì)應(yīng)的父元素里that.ul.insertAdjacentHTML('beforeend', li);that.fsection.insertAdjacentHTML('beforeend', section);that.init();}// 3、刪除功能removeTab() {}// 4、修改功能editTab() {} };new Tab('#tab');3.1.4 刪除功能模塊
- 為元素的刪除按鈕x綁定點(diǎn)擊事件;
- 獲取到點(diǎn)擊的刪除按鈕的所在的父元素的index,刪除對(duì)應(yīng)的標(biāo)題與內(nèi)容。
注意:
在tab類(lèi)的刪除方法中處理: 點(diǎn)擊x獲取對(duì)應(yīng)的索引,注意獲取的索引號(hào)是當(dāng)前x號(hào)的父元素的索引,要讀取parentNode.index。
因?yàn)閠ab標(biāo)題本身有點(diǎn)擊事件,x號(hào)的點(diǎn)擊事件會(huì)向上傳遞,需要阻止事件冒泡。
獲取所有tab標(biāo)題的x按鈕并為每一個(gè)tab標(biāo)題的x號(hào)綁定點(diǎn)擊事件(一定要在更新的方法中獲取,否則新添加的tab欄獲取不到,代碼會(huì)報(bào)錯(cuò))
// 3、刪除功能removeTab(e) {e.stopPropagation(); // 陰止冒泡 防止觸發(fā)li的切換點(diǎn)擊事件var index = this.parentNode.index;// 根據(jù)索引號(hào)刪除對(duì)應(yīng)的li和section remove() 方法可以直接刪除指定的元素that.lis[index].remove();that.sections[index].remove();that.init();// 如果刪除的不是選中狀態(tài)的li,原來(lái)的選中狀態(tài)li保持不變if (document.querySelector('.liactive')) return;// 如果刪除了選中狀態(tài)的列,需要設(shè)置它的前一個(gè)li為選中狀態(tài)index--;// click 調(diào)用點(diǎn)擊事件,不需要鼠標(biāo)觸發(fā)that.lis[index] && that.lis[index].click();}總結(jié):
- 將記錄下來(lái)的索引找到對(duì)應(yīng)的tab標(biāo)題和tab內(nèi)容刪除。remove() 方法可以直接刪除指定的元素;
- 重新初始化tab標(biāo)題與tab內(nèi)容的數(shù)量;
- 點(diǎn)擊刪除選中狀態(tài)的tab的標(biāo)題后讓前一個(gè)tab標(biāo)題選中;
- 將索引自減;
- 手動(dòng)調(diào)用click事件。
1)將索引自減代碼that.lis[index] && that.lis[index].click() 中的&& 符號(hào),表示如果左邊為真,才執(zhí)行右邊的代碼。
2)if (document.querySelector('.liactive')) :如果有處于選定狀態(tài)的列,就return,下面的代碼不再執(zhí)行。
3.1.5 編輯功能模塊
雙擊選項(xiàng)卡li或section里面的文字,可以實(shí)現(xiàn)修改操作。
- 為元素(標(biāo)題與內(nèi)容)綁定雙擊事件ondblclick;
- 在雙擊事件處理文本選中狀態(tài),修改內(nèi)部DOM節(jié)點(diǎn),實(shí)現(xiàn)新舊value值的傳遞。
核心思路:
雙擊文字時(shí),在里面生成一個(gè)文本框;
當(dāng)失去焦點(diǎn)或是按下回車(chē),就把文本框的值給原先元素即可。
注:如果雙擊,會(huì)默認(rèn)選定文字,此時(shí)需要雙擊禁止選中文字。
雙擊禁止選中文字的代碼:
1)為元素(標(biāo)題與內(nèi)容)綁定雙擊事件
this.spans[i].ondblclick = this.editTab; this.sections[i].ondblclick = this.editTab;文本框失去焦點(diǎn)時(shí),將文本框里的值再賦給span
input.onblur = function() {this.parentNode.innerHTML = this.value; }當(dāng)敲下回車(chē)時(shí),也能夠把文本框的值給span
input.onkeyup = function(e) {if (e.keyCode === 13) {//手動(dòng)調(diào)用失去焦點(diǎn)事件,不需鼠標(biāo)離開(kāi)操作this.onblur();}}利用了鍵盤(pán)事件里的事件對(duì)象。
修改模塊的代碼:
// 4、修改功能editTab() {// 獲取原先的內(nèi)容var str = this.innerHTML;// 雙擊禁止選定文字window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();this.innerHTML = '<input type="text" />';// 獲取文本框var input = this.children[0];input.value = str; //將原先span里的文字賦值給文本框// 讓文本框里的文字處于選定狀態(tài)input.select();//文本框失去焦點(diǎn)時(shí),將文本框里的值再賦給spaninput.onblur = function() {this.parentNode.innerHTML = this.value;}//敲下回車(chē)時(shí),也能夠把文本框的值給spaninput.onkeyup = function(e) {if (e.keyCode === 13) {//手動(dòng)調(diào)用失去焦點(diǎn)事件,不需鼠標(biāo)離開(kāi)操作this.onblur();}}}至此,已完成Tab欄的切換、增、刪、改功能
總結(jié)
以上是生活随笔為你收集整理的JavaScript从入门到放弃 - ES6中的对象和类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 你所不知道的 JavaScript
- 下一篇: JavaScript DOM编程艺术(第