前端學(xué)習(xí)筆記十三-面向?qū)ο?/h1>

一铭段、面向過程與面向?qū)ο?/h3>

1.1 面向過程(POP)

  • 面向過程就是分析出解決問題所需要的步驟畜份,然后用函數(shù)把這些步驟一步一步實現(xiàn)顿仇,使用的時候再一個一個的依次調(diào)用就可以了玄叠。

例子:1.打開冰箱??2.把大象裝進去??3.把冰箱門關(guān)上

1.2 面向?qū)ο螅∣OP)

  • 面向?qū)ο笫前咽聞?wù)分解成為一個個對象古徒,然后由對象之間分工與合作。

以對象功能來劃分問題读恃。

例子:將大象裝進冰箱隧膘,面向?qū)ο笞龇ā?br> 先找出對象,并寫出這些對象的功能:
1. 大象對象:

  • 進去

2. 冰箱對象:

  • 打開
  • 關(guān)閉

3. 使用大象和冰箱的功能

1.3 面向過程與面向?qū)ο髮Ρ?/h4>
面向過程 面向?qū)ο?/th>
優(yōu)點 性能比面向?qū)ο蟾吆唬m合跟硬件聯(lián)系很緊密的東西舀寓,例如單片機就采用的面向過程編程。適合比較簡單的小型程序肌蜻。 易維護互墓、易復(fù)用、易擴展蒋搜,由于面向?qū)ο笥?strong>封裝性篡撵、繼承性、多態(tài)性的特性豆挽,可以設(shè)計出低耦合的系統(tǒng)育谬,使系統(tǒng) 更加靈活、更加易于維護帮哈。適合多人合作的大型項目膛檀。
缺點 不易維護、不易復(fù)用娘侍、不易擴展 性能比面向過程低

面向過程和面向?qū)ο笾皇菍τ诰幊趟季S的一種描述咖刃,面向過程的方法寫出來的程序就像蛋炒飯,如果里面某些食材不愛吃很難挑出來憾筏;而用面向?qū)ο髮懙某绦蚋裆w澆飯嚎杨,自己想要什么澆頭自己取用就可。

1.4 面向?qū)ο蟮乃季S特點

  1. 抽妊跹(抽象)對象共用的屬性和行為封裝成一個類(模版)
  2. 對類進行實例化枫浙,產(chǎn)生具體的一個個對象

二刨肃、對象與類

2.1 對象

對象是由屬性和方法組成的:是一個無序鍵值對(相關(guān)屬性與方法)的集合,指的是一個具體的事物。所有的事物都是對象箩帚,例如字符串真友、數(shù)值、數(shù)組膏潮、函數(shù)等锻狗。

  • 屬性:事物的特征,在對象中用屬性來表示(常用名詞)
  • 方法:事物的行為焕参,在對象中用方法來表示(常用動詞)
2.1.1 創(chuàng)建對象
//以下代碼是對對象的復(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)//實例化對象
console.log(ldh);   

如上兩行代碼運行結(jié)果為:

2.2 類

  • 在 ES6 中新增加了類的概念,可以使用 class 關(guān)鍵字聲明一個類油额,之后以這個類來實例化對象叠纷。類抽象了對象的公共部分,它泛指某一大類(class)潦嘶。對象特指某一個涩嚣,通過類實例化一個具體的對象
2.2.1創(chuàng)建類
  1. 語法:
//步驟1 使用class關(guān)鍵字
class Name {
  // class body
}     
//步驟2使用定義的類創(chuàng)建實例  注意new關(guān)鍵字
var xx = new Name();     

constructor構(gòu)造函數(shù)(構(gòu)造器)
constructor()方法是類的構(gòu)造函數(shù)(默認方法),用于傳遞參數(shù)掂僵,返回實例對象航厚,通過new命令生成對象實例時,自動調(diào)用該方法锰蓬。如果我門定義類的時候沒有寫幔睬,類內(nèi)部會自動給我們創(chuàng)建一個constructor()

  1. 示例
 // 1. 創(chuàng)建類 class  創(chuàng)建一個 明星類
 class Star {
     // 類的共有屬性放到 constructor 里面
     constructor(name, age) {
         this.name = name;
         this.age = age;
     }
 }
   // 2. 利用類創(chuàng)建對象 new
   var ldh = new Star('劉德華', 18);
   console.log(ldh);

以上代碼運行結(jié)果:

通過結(jié)果我們可以看出,運行結(jié)果和使用構(gòu)造函數(shù)方式一樣

2.2.2 類創(chuàng)建添加屬性和方法
 // 1. 創(chuàng)建類 class  創(chuàng)建一個類
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('冰雨'); // 劉德華唱冰雨

注意:

  1. 通過class 關(guān)鍵字創(chuàng)建類, 類名我們還是習(xí)慣性定義首字母大寫
  2. 類里面有個constructor 函數(shù),可以接受傳遞過來的參數(shù),同時返回實例對象
  3. constructor 函數(shù) 只要 new 生成實例時,就會自動調(diào)用這個函數(shù), 如果我們不寫這個函數(shù),類也會自動生成這個函數(shù)
  4. 多個函數(shù)方法之間不需要添加逗號分隔
  5. 生成實例 new 不能省略
  6. 語法規(guī)范, 創(chuàng)建類 類名后面不要加小括號,生成實例 類名后面加小括號, 構(gòu)造函數(shù)不需要加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();      //結(jié)果為 你的姓是劉

以上代碼運行結(jié)果:

  • 子類使用super關(guān)鍵字訪問父類的方法
//定義了父類
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調(diào)用了父類中的構(gòu)造函數(shù)
    }
}
var son = new Son(1, 2);
son.sum(); //結(jié)果為3

注意:

  1. 繼承中,如果實例化子類輸出一個方法,先看子類有沒有這個方法,如果有就先執(zhí)行子類的

  2. 繼承中,如果子類里面沒有,就去查找父類有沒有這個方法,如果有,就執(zhí)行父類的這個方法(就近原則)

  3. 如果子類想要繼承父類的方法,同時在自己內(nèi)部擴展自己的方法,利用super 調(diào)用父類的構(gòu)造函數(shù),super必須在子類this之前調(diào)用

// 父類有加法方法
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 調(diào)用父類的構(gòu)造函數(shù) super 必須在子類this之前調(diào)用,放到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

以上代碼運行結(jié)果為:

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

    • constructor中的this指向的是new出來的實例對象
    • 自定義的方法,一般也指向的new出來的實例對象
    • 綁定事件之后this指向的就是觸發(fā)事件的事件源
  2. 在 ES6 中類沒有變量提升芹扭,所以必須先定義類麻顶,才能通過類實例化對象

三、面向?qū)ο蟀鎡ab 欄切換

3.1 功能需求

  1. 點擊 tab欄,可以切換效果.
  2. 點擊 + 號, 可以添加 tab 項和內(nèi)容項.
  3. 點擊 x 號, 可以刪除當前的tab項和內(nèi)容項.
  4. 雙擊tab項文字或者內(nèi)容項文字可以修改里面的文字內(nèi)容

3.2 案例準備

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

3.3 切換

  • 為獲取到的標題綁定點擊事件,展示對應(yīng)的內(nèi)容區(qū)域,存儲對應(yīng)的索引

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

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

3.4 添加

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

     this.add.onclick = this.addTab;
    
  • 實現(xiàn)標題與內(nèi)容的添加,做好排他處理

    addTab() {
        that.clearClass();
        // (1) 創(chuàng)建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) 把這兩個元素追加到對應(yīng)的父元素里面
        that.ul.insertAdjacentHTML('beforeend', li);
        that.fsection.insertAdjacentHTML('beforeend', section);
        that.init();
        }
    

3.5 刪除

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

     this.remove[i].onclick = this.removeTab;
    
  • 獲取到點擊的刪除按鈕的所在的父元素的所有,刪除對應(yīng)的標題與內(nèi)容

     removeTab(e) {
         e.stopPropagation(); // 阻止冒泡 防止觸發(fā)li 的切換點擊事件
         var index = this.parentNode.index;
         console.log(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)的這個li 的時候, 讓它的前一個li 處于選定狀態(tài)
         index--;
         // 手動調(diào)用我們的點擊事件  不需要鼠標觸發(fā)
         that.lis[index] && that.lis[index].click();
     }
    

3.6 編輯

  • 為元素(標題與內(nèi)容)綁定雙擊事件

     this.spans[i].ondblclick = this.editTab;
     this.sections[i].ondblclick = this.editTab;
    
  • 在雙擊事件處理文本選中狀態(tài),修改內(nèi)部DOM節(jié)點,實現(xiàn)新舊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(); // 文本框里面的文字處于選定狀態(tài)
          // 當我們離開文本框就把文本框里面的值給span 
          input.onblur = function() {
          this.parentNode.innerHTML = this.value;
          };
          // 按下回車也可以把文本框里面的值給span
          input.onkeyup = function(e) {
          if (e.keyCode === 13) {
          // 手動調(diào)用表單失去焦點事件  不需要鼠標離開操作
          this.blur();
          }
        }
    }
    

四舱卡、構(gòu)造函數(shù)和原型

4.1 對象的三種創(chuàng)建方式--復(fù)習(xí)

  1. 字面量方式

    var obj = {};
    
  2. new關(guān)鍵字

    var obj = new Object();
    
  3. 構(gòu)造函數(shù)方式

    function Person(name,age){
      this.name = name;
      this.age = age;
    }
    var obj = new Person('zs',12);
    

4.2 靜態(tài)成員和實例成員

4.2.1 實例成員

實例成員就是構(gòu)造函數(shù)內(nèi)部通過this添加的成員 如下列代碼中uname age sing 就是實例成員辅肾,實例成員只能通過實例化的對象來訪問

 function Star(uname, age) {
     this.uname = uname;
     this.age = age;
     this.sing = function() {
     console.log('我會唱歌');
    }
}
var ldh = new Star('劉德華', 18);
console.log(ldh.uname);//實例成員只能通過實例化的對象來訪問
4.2.2 靜態(tài)成員

靜態(tài)成員 在構(gòu)造函數(shù)本身上添加的成員 如下列代碼中 sex 就是靜態(tài)成員,靜態(tài)成員只能通過構(gòu)造函數(shù)來訪問

 function Star(uname, age) {
     this.uname = uname;
     this.age = age;
     this.sing = function() {
     console.log('我會唱歌');
    }
}
Star.sex = '男';
var ldh = new Star('劉德華', 18);
console.log(Star.sex);//靜態(tài)成員只能通過構(gòu)造函數(shù)來訪問

4.3 構(gòu)造函數(shù)的問題

構(gòu)造函數(shù)方法很好用,但是存在浪費內(nèi)存的問題轮锥。

4.4 構(gòu)造函數(shù)原型prototype

構(gòu)造函數(shù)通過原型分配的函數(shù)是所有對象所共享的矫钓。

JavaScript 規(guī)定,每一個構(gòu)造函數(shù)都有一個prototype 屬性舍杜,指向另一個對象新娜。注意這個prototype就是一個對象,這個對象的所有屬性和方法蝴簇,都會被構(gòu)造函數(shù)所擁有杯活。

我們可以把那些不變的方法,直接定義在 prototype 對象上熬词,這樣所有對象的實例就可以共享這些方法旁钧。

function Star(uname, age) {
    this.uname = uname;
    this.age = age;
}
Star.prototype.sing = function() {
    console.log('我會唱歌');
}
var ldh = new Star('劉德華', 18);
var zxy = new Star('張學(xué)友', 19);
ldh.sing();//我會唱歌
zxy.sing();//我會唱歌

4.5 對象原型

對象都會有一個屬性__proto__ 指向構(gòu)造函數(shù)的 prototype 原型對象吸重,之所以我們對象可以使用構(gòu)造函數(shù) prototype 原型對象的屬性和方法,就是因為對象有__proto__原型的存在歪今。
__proto__對象原型和原型對象 prototype 是等價的
__proto__對象原型的意義就在于為對象的查找機制提供一個方向嚎幸,或者說一條路線,但是它是一個非標準屬性寄猩,因此實際開發(fā)中嫉晶,不可以使用這個屬性,它只是內(nèi)部指向原型對象 prototype

4.6 constructor構(gòu)造函數(shù)

對象原型(__proto__)和構(gòu)造函數(shù)(prototype)原型對象里面都有一個屬性 constructor 屬性 田篇,constructor 我們稱為構(gòu)造函數(shù)替废,因為它指回構(gòu)造函數(shù)本身。
constructor 主要用于記錄該對象引用于哪個構(gòu)造函數(shù)泊柬,它可以讓原型對象重新指向原來的構(gòu)造函數(shù)椎镣。
一般情況下,對象的方法都在構(gòu)造函數(shù)的原型對象中設(shè)置兽赁。如果有多個對象的方法状答,我們可以給原型對象采取對象形式賦值,但是這樣就會覆蓋構(gòu)造函數(shù)原型對象原來的內(nèi)容刀崖,這樣修改后的原型對象 constructor 就不再指向當前構(gòu)造函數(shù)了惊科。此時,我們可以在修改后的原型對象中亮钦,添加一個 constructor 指向原來的構(gòu)造函數(shù)馆截。

如果我們修改了原來的原型對象,給原型對象賦值的是一個對象,則必須手動的利用constructor指回原來的構(gòu)造函數(shù)如:

 function Star(uname, age) {
     this.uname = uname;
     this.age = age;
 }
 // 很多情況下,我們需要手動的利用constructor 這個屬性指回 原來的構(gòu)造函數(shù)
 Star.prototype = {
 // 如果我們修改了原來的原型對象,給原型對象賦值的是一個對象,則必須手動的利用constructor指回原來的構(gòu)造函數(shù)
   constructor: Star, // 手動設(shè)置指回原來的構(gòu)造函數(shù)
   sing: function() {
     console.log('我會唱歌');
   },
   movie: function() {
     console.log('我會演電影');
   }
}
var zxy = new Star('張學(xué)友', 19);
console.log(zxy)

以上代碼運行結(jié)果,設(shè)置constructor屬性如圖:


如果未設(shè)置constructor屬性,如圖:

4.7 原型鏈

? 每一個實例對象又有一個__proto__屬性,指向的構(gòu)造函數(shù)的原型對象(prototype)或悲,構(gòu)造函數(shù)的原型對象也是一個對象孙咪,也有__proto__屬性,這樣一層一層往上找就形成了原型鏈巡语。

4.8 構(gòu)造函數(shù)實例和原型對象三角關(guān)系

  1. 構(gòu)造函數(shù)的prototype屬性指向了構(gòu)造函數(shù)原型對象
  2. 實例對象是由構(gòu)造函數(shù)創(chuàng)建的,實例對象的__proto__屬性指向了構(gòu)造函數(shù)的原型對象
  3. 構(gòu)造函數(shù)的原型對象的constructor屬性指向了構(gòu)造函數(shù)翎蹈,實例對象的原型的constructor屬性也指向了構(gòu)造函數(shù)

4.9 原型鏈和成員的查找機制

任何對象都有原型對象,也就是prototype屬性,任何原型對象也是一個對象,該對象就有__proto__屬性,這樣一層一層往上找,就形成了一條鏈,我們稱此為原型鏈;

當訪問一個對象的屬性(包括方法)時,首先查找這個對象自身有沒有該屬性男公。
如果沒有就查找它的原型(也就是 __proto__指向的 prototype 原型對象)荤堪。
如果還沒有就查找原型對象的原型(Object的原型對象)。
依此類推一直找到 Object 為止(null)枢赔。
__proto__對象原型的意義就在于為對象成員查找機制提供一個方向澄阳,或者說一條路線。

4.10 原型對象中this指向

構(gòu)造函數(shù)中的this和原型對象的this踏拜,都指向我們new出來的實例對象

function Star(uname, age) {
    this.uname = uname;
    this.age = age;
}
var that;
Star.prototype.sing = function() {
    console.log('我會唱歌');
    that = this;
}
var ldh = new Star('劉德華', 18);
// 1. 在構(gòu)造函數(shù)中,里面this指向的是對象實例 ldh
console.log(that === ldh);//true
// 2.原型對象函數(shù)里面的this 指向的是 實例對象 ldh

4.11 通過原型為數(shù)組擴展內(nèi)置方法

 Array.prototype.sum = function() {
   var sum = 0;
   for (var i = 0; i < this.length; i++) {
   sum += this[i];
   }
   return sum;
 };
 //此時數(shù)組對象中已經(jīng)存在sum()方法了  可以始終 數(shù)組.sum()進行數(shù)據(jù)的求

五碎赢、組合繼承

5.1 call()

  • call()可以調(diào)用函數(shù)fn.call()
  • call()可以修改this的指向,使用call()的時候 參數(shù)一是修改后的this指向,參數(shù)2,參數(shù)3..使用逗號隔開連接
 function fn(x, y) {
     console.log(this);
     console.log(x + y);
}
  var o = {
    name: 'andy'
  };
  fn.call(o, 1, 2);//調(diào)用了函數(shù)此時的this指向了對象o,

5.2 子構(gòu)造函數(shù)繼承父構(gòu)造函數(shù)中的屬性

  1. 先定義一個父構(gòu)造函數(shù)
  2. 再定義一個子構(gòu)造函數(shù)
  3. 子構(gòu)造函數(shù)繼承父構(gòu)造函數(shù)的屬性(使用call方法)
 // 1. 父構(gòu)造函數(shù)
 function Father(uname, age) {
   // this 指向父構(gòu)造函數(shù)的對象實例
   this.uname = uname;
   this.age = age;
 }
  // 2 .子構(gòu)造函數(shù) 
function Son(uname, age, score) {
  // this 指向子構(gòu)造函數(shù)的對象實例
  3.使用call方式實現(xiàn)子繼承父的屬性
  Father.call(this, uname, age);
  this.score = score;
}
var son = new Son('劉德華', 18, 100);
console.log(son);

5.3 借用原型對象繼承方法

  1. 先定義一個父構(gòu)造函數(shù)
  2. 再定義一個子構(gòu)造函數(shù)
  3. 子構(gòu)造函數(shù)繼承父構(gòu)造函數(shù)的屬性(使用call方法)
// 1. 父構(gòu)造函數(shù)
function Father(uname, age) {
  // this 指向父構(gòu)造函數(shù)的對象實例
  this.uname = uname;
  this.age = age;
}
Father.prototype.money = function() {
  console.log(100000);
 };
 // 2 .子構(gòu)造函數(shù) 
  function Son(uname, age, score) {
      // this 指向子構(gòu)造函數(shù)的對象實例
      Father.call(this, uname, age);
      this.score = score;
  }
// Son.prototype = Father.prototype;  這樣直接賦值會有問題,因為是把父原型對象的地址給了子原型對象速梗;如果修改了子原型對象肮塞,父原型對象也會跟著一起變化
  Son.prototype = new Father();
  // 如果利用對象的形式修改了原型對象,別忘了利用constructor 指回原來的構(gòu)造函數(shù)
  Son.prototype.constructor = Son;
  // 這個是子構(gòu)造函數(shù)專門的方法
  Son.prototype.exam = function() {
    console.log('孩子要考試');

  }
  var son = new Son('劉德華', 18, 100);
  console.log(son);

如上代碼結(jié)果如圖:

六襟齿、ES5新增方法

6.1 數(shù)組方法forEach遍歷數(shù)組

 arr.forEach(function(value, index, array) {
       //參數(shù)一是:數(shù)組元素
       //參數(shù)二是:數(shù)組元素的索引
       //參數(shù)三是:當前的數(shù)組
 })
  //相當于數(shù)組遍歷的 for循環(huán) 沒有返回值

6.2 數(shù)組方法filter過濾數(shù)組

  var arr = [12, 66, 4, 88, 3, 7];
  var newArr = arr.filter(function(value,index,array) {
     //參數(shù)一是:數(shù)組元素
     //參數(shù)二是:數(shù)組元素的索引
     //參數(shù)三是:當前的數(shù)組
     return value >= 20;
  });
  console.log(newArr);//[66,88] //返回值是一個新數(shù)組

6.3 數(shù)組方法map處理數(shù)組

通過指定函數(shù)處理數(shù)組的每個元素,并返回處理后的數(shù)組

var arr = [1,2,3,4,5,4,3,2,1];
var mapResult = arr.map(function(item, index, array){
    return item * 2;
});
console.log(mapResult);    // [2,4,6,8,10,8,6,4,2]

6.4 數(shù)組方法some和every

按順序查找數(shù)組中是否有滿足條件的元素枕赵,只要有1個符合條件就返回true猜欺,然后立即終止循環(huán),而every()是執(zhí)行到最后一項拷窜,必須每一項都符合條件才會返回true

 var arr = [10, 30, 4];
 var flag = arr.some(function(value,index,array) {
    //參數(shù)一是:數(shù)組元素
     //參數(shù)二是:數(shù)組元素的索引
     //參數(shù)三是:當前的數(shù)組
     return value < 3;
  });
console.log(flag);//false返回值是布爾值,只要查找到滿足條件的一個元素就立馬終止循環(huán)

6.5 篩選商品案例

  1. 定義數(shù)組對象數(shù)據(jù)

    var data = [{
                id: 1,
                pname: '小米',
                price: 3999
            }, {
                id: 2,
                pname: 'oppo',
                price: 999
            }, {
                id: 3,
                pname: '榮耀',
                price: 1299
            }, {
                id: 4,
                pname: '華為',
                price: 1999
            }, ];
    
  2. 使用forEach遍歷數(shù)據(jù)并渲染到頁面中

    data.forEach(function(value) {
      var tr = document.createElement('tr');
      tr.innerHTML = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>';
      tbody.appendChild(tr);
     });
    
  3. 根據(jù)價格篩選數(shù)據(jù)

    1. 獲取到搜索按鈕并為其綁定點擊事件

      search_price.addEventListener('click', function() {
      });
      
    2. 使用filter將用戶輸入的價格信息篩選出來

      search_price.addEventListener('click', function() {
            var newDate = data.filter(function(value) {
              //start.value是開始區(qū)間
              //end.value是結(jié)束的區(qū)間
                return value.price >= start.value && value.price <= end.value;
            });
            console.log(newDate);
       });
      
    3. 將篩選出來的數(shù)據(jù)重新渲染到表格中

      1. 將渲染數(shù)據(jù)的邏輯封裝到一個函數(shù)中

        function setDate(mydata) {
              // 先清空原來tbody 里面的數(shù)據(jù)
          tbody.innerHTML = '';
          mydata.forEach(function(value) {
            var tr = document.createElement('tr');
            tr.innerHTML = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>';
              tbody.appendChild(tr);
          });
         }
        
      2. 將篩選之后的數(shù)據(jù)重新渲染

         search_price.addEventListener('click', function() {
             var newDate = data.filter(function(value) {
             return value.price >= start.value && value.price <= end.value;
             });
             console.log(newDate);
             // 把篩選完之后的對象渲染到頁面中
             setDate(newDate);
        });
        
    4. 根據(jù)商品名稱篩選

      1. 獲取用戶輸入的商品名稱

      2. 為查詢按鈕綁定點擊事件,將輸入的商品名稱與這個數(shù)據(jù)進行篩選

         search_pro.addEventListener('click', function() {
             var arr = [];
             data.some(function(value) {
               if (value.pname === product.value) {
                 // console.log(value);
                 arr.push(value);
                 return true; // return 后面必須寫true  
               }
             });
             // 把拿到的數(shù)據(jù)渲染到頁面中
             setDate(arr);
        })
        

6.6 some和forEach區(qū)別

  • 如果查詢數(shù)組中唯一的元素, 用some方法更合適开皿,在some里面遇到 return true 就是終止遍歷,迭代效率更高
  • 在forEach 里面 return 不會終止迭代

6.7 trim方法去除字符串兩端的空格

不影響原字符串篮昧,返回的是新字符串

var str = '   hello   '
console.log(str.trim())  //hello 去除兩端空格
var str1 = '   he l l o   '
console.log(str1.trim())  //he l l o  去除兩端空格

6.8 獲取對象的屬性名

Object.keys(對象) 獲取到當前對象中的屬性名 赋荆,返回值是一個數(shù)組

 var obj = {
     id: 1,
     pname: '小米',
     price: 1999,
     num: 2000
};
var result = Object.keys(obj)
console.log(result)//[id,pname,price,num]

6.9 Object.defineProperty

Object.defineProperty設(shè)置或修改對象中的屬性

Object.defineProperty(對象obj懊昨,修改或新增的屬性名prop字符串糠睡,{
    value:修改或新增的屬性的值,默認為undefined。
    writable:true|false,//默認為false疚颊。即不允許修改這個屬性的值
    enumerable: false,//enumerable 默認值為false,即不允許遍歷(枚舉)信认。Object.keys(obj)將沒有這個屬性名
    configurable: false  //configurable 默認值為false材义,即不允許刪除這個屬性 屬性是否可以被刪除或是否可以再次修改特性(即用Object.defineProperty再次設(shè)置這個屬性的第三個參數(shù))
})  
var obj = {
    id: 1,
    pname: '小米',
    price: 1999
};

// Object.defineProperty() 定義新屬性或修改原有的屬性
Object.defineProperty(obj, 'num', {
     value: 1000,
     enumerable: true
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嫁赏,隨后出現(xiàn)的幾起案子其掂,更是在濱河造成了極大的恐慌,老刑警劉巖潦蝇,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件款熬,死亡現(xiàn)場離奇詭異,居然都是意外死亡攘乒,警方通過查閱死者的電腦和手機贤牛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來则酝,“玉大人殉簸,你說我怎么就攤上這事」炼铮” “怎么了般卑?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長爽雄。 經(jīng)常有香客問我蝠检,道長,這世上最難降的妖魔是什么挚瘟? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任叹谁,我火速辦了婚禮饲梭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘本慕。我一直安慰自己排拷,他們只是感情好,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布锅尘。 她就那樣靜靜地躺著监氢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪藤违。 梳的紋絲不亂的頭發(fā)上浪腐,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機與錄音顿乒,去河邊找鬼议街。 笑死,一個胖子當著我的面吹牛璧榄,可吹牛的內(nèi)容都是我干的特漩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼骨杂,長吁一口氣:“原來是場噩夢啊……” “哼涂身!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起搓蚪,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蛤售,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后妒潭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悴能,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年雳灾,在試婚紗的時候發(fā)現(xiàn)自己被綠了漠酿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡佑女,死狀恐怖记靡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情团驱,我是刑警寧澤摸吠,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嚎花,受9級特大地震影響寸痢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜紊选,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一啼止、第九天 我趴在偏房一處隱蔽的房頂上張望道逗。 院中可真熱鬧,春花似錦献烦、人聲如沸滓窍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吏夯。三九已至,卻和暖如春即横,著一層夾襖步出監(jiān)牢的瞬間噪生,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工东囚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留跺嗽,地道東北人。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓页藻,卻偏偏與公主長得像桨嫁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子份帐,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容