JavaScript高級-類的使用

1.面向過程與面向對象

1.1面向過程

  • 面向過程就是分析出解決問題所須要的步驟,而後用函數把這些步驟一步一步實現,使用的時候再一個一個的依次調用就能夠了。

1.2面向對象

  • 面向對象是把事務分解成爲一個個對象,而後由對象之間分工與合做。

1.3面向過程與面向對象對比

  面向過程 面向對象
優勢 性能比面向對象高,適合跟硬件聯繫很緊密的東西,例如單片機就採用的面向過程編程。 易維護、易複用、易擴展,因爲面向對象有封裝、繼承、多態性的特性,能夠設計出低耦合的系統,使系統 更加靈活、更加易於維護
缺點 不易維護、不易複用、不易擴展 性能比面向過程低

2.對象與類

2.1對象

對象是由屬性和方法組成的:是一個無序鍵值對的集合,指的是一個具體的事物html

  • 屬性:事物的特徵,在對象中用屬性來表示(經常使用名詞)
  • 方法:事物的行爲,在對象中用方法來表示(經常使用動詞)

2.1.1建立對象

//如下代碼是對對象的複習 //字面量建立對象 var ldh = { name: '劉德華', age: 18 } console.log(ldh); //構造函數建立對象 function Star(name, age) { this.name = name; this.age = age; } var ldh = new Star('劉德華', 18)//實例化對象 console.log(ldh); 

如上兩行代碼運行結果爲:
在這裏插入圖片描述編程

2.2類

  • 在 ES6 中新增長了類的概念,可使用 class 關鍵字聲明一個類,以後以這個類來實例化對象。類抽象了對象的公共部分,它泛指某一大類(class)對象特指某一個,經過類實例化一個具體的對象

2.2.1建立類

  1. 語法:
//步驟1 使用class關鍵字 class name { // class body } //步驟2使用定義的類建立實例 注意new關鍵字 var xx = new name(); 
  1. 示例
// 1. 建立類 class 建立一個 明星類 class Star { // 類的共有屬性放到 constructor 裏面 constructor(name, age) { this.name = name; this.age = age; } } // 2. 利用類建立對象 new var ldh = new Star('劉德華', 18); console.log(ldh); 

以上代碼運行結果:dom

在這裏插入圖片描述

經過結果咱們能夠看出,運行結果和使用構造函數方式同樣函數

2.2.2類建立添加屬性和方法

// 1. 建立類 class 建立一個類 class Star { // 類的共有屬性放到 constructor 裏面 constructor是 構造器或者構造函數 constructor(uname, age) { this.uname = uname; this.age = age; }//------------------------------------------->注意,方法與方法之間不須要添加逗號 sing(song) { console.log(this.uname + '唱' + song); } } // 2. 利用類建立對象 new var ldh = new Star('劉德華', 18); console.log(ldh); // Star {uname: "劉德華", age: 18} ldh.sing('冰雨'); // 劉德華唱冰雨 

以上代碼運行結果:性能

在這裏插入圖片描述

注意喲:測試

  1. 經過class 關鍵字建立類, 類名咱們仍是習慣性定義首字母大寫
  2. 類裏面有個constructor 函數,能夠接受傳遞過來的參數,同時返回實例對象
  3. constructor 函數 只要 new 生成實例時,就會自動調用這個函數, 若是咱們不寫這個函數,類也會自動生成這個函數
  4. 多個函數方法之間不須要添加逗號分隔
  5. 生成實例 new 不能省略
  6. 語法規範, 建立類 類名後面不要加小括號,生成實例 類名後面加小括號, 構造函數不須要加function

2.2.3類的繼承

  1. 語法
// 父類 class Father{ } // 子類繼承父類 class Son extends Father { } 
  1. 示例
class Father { constructor(surname) { this.surname= surname; } say() { console.log('你的姓是' + this.surname); } } class Son extends Father{ // 這樣子類就繼承了父類的屬性和方法 } var damao= new Son('劉'); damao.say(); //結果爲 你的姓是劉 

以上代碼運行結果:this

在這裏插入圖片描述

  • 子類使用super關鍵字訪問父類的方法spa

    //定義了父類 class Father { constructor(x, y) { this.x = x; this.y = y; } sum() { console.log(this.x + this.y); } } //子元素繼承父類 class Son extends Father { constructor(x, y) { super(x, y); //使用super調用了父類中的構造函數 } } var son = new Son(1, 2); son.sum(); //結果爲3 

    注意:設計

    1. 繼承中,若是實例化子類輸出一個方法,先看子類有沒有這個方法,若是有就先執行子類的3d

    2. 繼承中,若是子類裏面沒有,就去查找父類有沒有這個方法,若是有,就執行父類的這個方法(就近原則)

    3. 若是子類想要繼承父類的方法,同時在本身內部擴展本身的方法,利用super 調用父類的構造函數,super 必須在子類this以前調用

      // 父類有加法方法 class Father { constructor(x, y) { this.x = x; this.y = y; } sum() { console.log(this.x + this.y); } } // 子類繼承父類加法方法 同時 擴展減法方法 class Son extends Father { constructor(x, y) { // 利用super 調用父類的構造函數 super 必須在子類this以前調用,放到this以後會報錯 super(x, y); this.x = x; this.y = y; } subtract() { console.log(this.x - this.y); } } var son = new Son(5, 3); son.subtract(); //2 son.sum();//8 

      以上代碼運行結果爲:

在這裏插入圖片描述

  1. 時刻注意this的指向問題,裏面的共有的屬性和方法必定要加this使用.

    1. constructor中的this指向的是new出來的實例對象
    2. 自定義的方法,通常也指向的new出來的實例對象
    3. 綁定事件以後this指向的就是觸發事件的事件源
  2. 在 ES6 中類沒有變量提高,因此必須先定義類,才能經過類實例化對象
    在這裏插入圖片描述

在這裏插入圖片描述

3.面向對象版tab 欄切換

3.1功能需求

  1. 點擊 tab欄,能夠切換效果.
  2. 點擊 + 號, 能夠添加 tab 項和內容項.
  3. 點擊 x 號, 能夠刪除當前的tab項和內容項.
  4. 雙擊tab項文字或者內容項文字能夠修改裏面的文字內容

3.2案例準備

  1. 獲取到標題元素
  2. 獲取到內容元素
  3. 獲取到刪除的小按鈕 x號
  4. 新建js文件,定義類,添加須要的屬性方法(切換,刪除,增長,修改)
  5. 時刻注意this的指向問題

3.3切換

  • 爲獲取到的標題綁定點擊事件,展現對應的內容區域,存儲對應的索引

    this.lis[i].index = i; this.lis[i].onclick = this.toggleTab; 
  • 使用排他,實現只有一個元素的顯示

    toggleTab() { //將全部的標題與內容類樣式所有移除 for (var i = 0; i < this.lis.length; i++) { this.lis[i].className = ''; this.sections[i].className = ''; } //爲當前的標題添加激活樣式 this.className = 'liactive'; //爲當前的內容添加激活樣式 that.sections[this.index].className = 'conactive'; } 

3.4添加

  • 爲添加按鈕+ 綁定點擊事件

    this.add.onclick = this.addTab; 
  • 實現標題與內容的添加,作好排他處理

    addTab() { that.clearClass(); // (1) 建立li元素和section元素 var random = Math.random(); var li = '<li class="liactive"><span>新選項卡</span><span class="iconfont icon-guanbi"> </span></li>'; var section = '<section class="conactive">測試 ' + random + '</section>'; // (2) 把這兩個元素追加到對應的父元素裏面 that.ul.insertAdjacentHTML('beforeend', li); that.fsection.insertAdjacentHTML('beforeend', section); that.init(); } 

3.5刪除

  • 爲元素的刪除按鈕x綁定點擊事件

    this.remove[i].onclick = this.removeTab; 
  • 獲取到點擊的刪除按鈕的所在的父元素的全部,刪除對應的標題與內容

    removeTab(e) { e.stopPropagation(); // 阻止冒泡 防止觸發li 的切換點擊事件 var index = this.parentNode.index; console.log(index); // 根據索引號刪除對應的li 和section remove()方法能夠直接刪除指定的元素 that.lis[index].remove(); that.sections[index].remove(); that.init(); // 當咱們刪除的不是選中狀態的li 的時候,原來的選中狀態li保持不變 if (document.querySelector('.liactive')) return; // 當咱們刪除了選中狀態的這個li 的時候, 讓它的前一個li 處於選定狀態 index--; // 手動調用咱們的點擊事件 不須要鼠標觸發 that.lis[index] && that.lis[index].click(); } 

3.6編輯

  • 爲元素(標題與內容)綁定雙擊事件

    this.spans[i].ondblclick = this.editTab; this.sections[i].ondblclick = this.editTab; 
  • 在雙擊事件處理文本選中狀態,修改內部DOM節點,實現新舊value值的傳遞

    editTab() { var str = this.innerHTML; // 雙擊禁止選定文字 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); // alert(11); this.innerHTML = '<input type="text" />'; var input = this.children[0]; input.value = str; input.select(); // 文本框裏面的文字處於選定狀態 // 當咱們離開文本框就把文本框裏面的值給span input.onblur = function() { this.parentNode.innerHTML = this.value; }; // 按下回車也能夠把文本框裏面的值給span input.onkeyup = function(e) { if (e.keyCode === 13) { // 手動調用表單失去焦點事件 不須要鼠標離開操做 this.blur(); } } } 

相關文章
相關標籤/搜索