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