ES6中定義類.繼承以及對象和數(shù)組的操作0712

ES6中定義類.繼承以及對象的操作0712

1.定義類的不同

回顧一下以前學習的在ES6之前定義一個類(不明顯,和普通的函數(shù)區(qū)別不大)
  •  function Person(myName, myAge) {
        // 實例屬性
        // this.name = "lnj";
        // this.age = 34;
        this.name = myName;
        this.age = myAge;
    
        // 實例方法
        this.say = function () {
            console.log(this.name, this.age);
        }
        // 靜態(tài)屬性
        Person.num = 666;
        // 靜態(tài)方法
        Person.run = function () {
            console.log("run");
        }
    }
    // let p = new Person();
    let p = new Person("zs", 18);
    p.say();
    console.log(Person.num);
    Person.run();
    
從ES6開始系統(tǒng)提供了一個名稱叫做class的關(guān)鍵字, 這個關(guān)鍵字就是專門用于定義類的(以后就這樣寫)
  • 注意里面的注意點哦

  •  class Person{
         // 當我們通過new創(chuàng)建對象的時候, 系統(tǒng)會自動調(diào)用constructor
         // constructor我們稱之為構(gòu)造函數(shù)
         constructor(myName, myAge){
             this.name = myName;
             this.age = myAge;
         }
         // 注意點:實例屬性,不是正式寫法,大部分瀏覽器不支持,所以我們還是寫在constructor里好
         // name = "lnj";
         // age = 34;
         // 注意點:實例方法,如果寫在constructor外面,系統(tǒng)會將這個方法添加到原型對象上面,想添加在實例對象上還是得寫在里面,所以定義在constructor外的方法就相當于以前定義在原型對象上的方法
         say(){
             console.log(this.name, this.age);
         }
         // 注意點:以下定義"靜態(tài)屬性"的方式并不是ES6正式版標準中的寫法, 大部分的瀏覽器不支持
         // 在ES標準中static只支持定義靜態(tài)方法不支持定義靜態(tài)變量,所以想要定義靜態(tài)屬性,應(yīng)定義在類外
         // 靜態(tài)屬性
         static num = 666;
         // 靜態(tài)方法
         static run() {
             console.log("run");
         }
     }
    //以下自定義一個原型對象在ES6中不可用,如果想將屬性和方法保存到原型中, 只能動態(tài)給原型對象添加屬性和方法
    let obj = {
              constructor: Person,
              type: "人",
              say: function () {
                  console.log(this.name, this.age);
              }
          };
    
     let p = new Person("zs", 18);
     p.say();
     console.log(Person.num);
     Person.run();
    

綜上所述,我們來寫一個最標準的類的定義

  •  class Person{
         constructor(myName, myAge){
             //方法和屬性都寫在里面
             this.name = myName;
             this.age = myAge;
             this.say = function(){
              console.log(this.name, this.age);
          }
         }
         //只能寫靜態(tài)方法
         static run() {
             console.log("run");
         }
     }
    //動態(tài)給原型對象添加方法和屬性
     Person.prototype.type = "人";
     Person.prototype.say = function () {
         console.log(this.name, this.age);
    };
    //靜態(tài)實行需要類外定義
     Person.num = 666;
    
     let p = new Person("zs", 18);
     p.say();
     console.log(Person.name);
     Person.run();
    

2.繼承的不同

  • 在ES6中如何繼承:在子類后面添加extends并指定父類的名稱,在子類的constructor構(gòu)造函數(shù)中通過super方法借助父類的構(gòu)造函數(shù)

  • class Person{
        constructor(myName, myAge){
            // this = stu;
            this.name = myName; // stu.name = myName;
            this.age = myAge; // stu.age = myAge;
        }
        say(){
            console.log(this.name, this.age);
        }
    }
    // 以下代碼的含義: 告訴瀏覽器將來Student這個類需要繼承于Person這個類
    class Student extends Person{
        constructor(myName, myAge, myScore){
            // 1.在子類中通過call/apply方法借助父類的構(gòu)造函數(shù)
            // Person.call(this, myName, myAge);相當于下面那條代碼
            super(myName, myAge);
            this.score = myScore;
        }
        study(){
            console.log("day day up");
        }
    }
    let stu = new Student("zs", 18, 98);
    stu.say();
    

3.獲取對象類型

現(xiàn)在我們有如下需求,獲取各自對應(yīng)的類型

  • /*
    let obj = new Object();  --> object
    let arr = new Array(); --> Array
    let p = new Person(); --> Person
    */
    console.log(typeof obj);
    console.log(typeof arr);
    console.log(typeof p);
    
  • 但是通過typeof獲取的類型都是object(理解一下),那怎么滿足我們的需求呢.看以下的

  •  function Person() {
        // let obj = new Object();
        // let this = obj;
        this.name = "lnj";
        this.age = 34;
        this.say = function () {
            console.log(this.name, this.age);
        }
        // return this;
    }
    let p = new Person();
    // console.log(typeof p); // object
    console.log(p.constructor.name); // Person
    
  • 為什么p.constructor.name 能獲得是什么類型呢,如下我們調(diào)用arr.constructor,就從原型對象找見了,然后指向了構(gòu)造函數(shù),構(gòu)造函數(shù)里面有一個name屬性就能得到是啥類型

  • [圖片上傳失敗...(image-692cc1-1562946030563)]

4. instanceOf關(guān)鍵字

什么是instanceof關(guān)鍵字?

  • instanceof用于判斷 "對象" 是否是指定構(gòu)造函數(shù)的 "實例"

  • 注意點: 只要構(gòu)造函數(shù)的原型對象出現(xiàn)在實例對象的原型鏈中都會返回true

  • 例如下面的例子

  •  function Person(myName) {
         this.name = myName;
     }
     function Student(myName, myScore) {
         Person.call(this, myName);
         this.score = myScore;
     }
     Student.prototype = new Person();
     Student.prototype.constructor = Student;
    
     let stu = new Student();
     console.log(stu instanceof Person); // true  這就說明了上面的觀點
     console.log(stu instanceof Student);
    

5.isPrototypeOf屬性

  • 什么是isPrototypeOf屬性

  • isPrototypeOf用于判斷 一個對象是否是另一個對象的原型 (前面的是不是后面的)

  • 注意點: 只要調(diào)用者在傳入對象的原型鏈上都會返回true

  • function Person(myName) {
         this.name = myName;
     }
     function Student(myName, myScore) {
         Person.call(this, myName);
         this.score = myScore;
     }
     Student.prototype = new Person();
     Student.prototype.constructor = Student;
    
     let stu = new Student();
     console.log(Person.prototype.isPrototypeOf(stu)); // true
    

6.判斷對象是否有某個屬性

6.1判斷某一個對象是否擁有某一個屬性
  • "屬性名" in 對象名
  • in的特點: 只要類中或者原型對象中有, 就會返回true
6.2 判斷某一個對象自身是否擁有某一個屬性
  • 對象名.hasOwnProperty("屬性名");
  • 特點: 只會去類中查找有沒有, 不會去原型對象中查找

7.對象的增刪改查

  •  class Person{}
    let p = new Person();
    
7.1增
  • p.name = "lnj";
  • p["name"] = "zs";
7.2 刪
  • delete p.name;
  • delete p["name"];
7.3 改
  • p.name = "lnj"; 覆蓋就行

8.對象遍歷

在JavaScript中對象和數(shù)組一樣是可以遍歷的

  • 對象的遍歷就是依次取出對象中所有的屬性和方法

在JS中可以通過高級for循環(huán)來遍歷對

  • for(let key in obj){}

  • 將指定對象中所有的屬性和方法的名稱取出來了依次的賦值給key這個變量

  • for(let key in p){
        if(p[key] instanceof Function){
            continue;
        }
        // console.log(key); // name / age / say
        // 注意點: 以下代碼的含義取出p對象中名稱叫做當前遍歷到的名稱的屬性或者方法的取值
        console.log(p[key]); // p["name"] / p["age"] / p["say"]
        // 注意點: 以下代碼的含義取出p對象中名稱叫做key的屬性的取值
        // console.log(p.key); // undefined
    }
    
js遍歷對象.png

10.深拷貝與淺拷貝

10.1深拷貝
  • 修改新變量的值不會影響原有變量的值
  • 默認情況下基本數(shù)據(jù)類型都是深拷貝
10.2淺拷貝
  • 修改新變量的值會影響原有的變量的值

  • 默認情況下引用類型都是淺拷貝

  • class Person{
         name = "lnj";
         age = 34;
     }
     let p1 = new Person();
     let p2 = p1;
     p2.name = "zs"; // 修改變量的值
     console.log(p1.name); //變?yōu)閦s
    
  • 原理如下

  • 淺拷貝.png
10.3 對象深拷貝

以下兩種只能拷貝基本數(shù)據(jù)類型

  • 1.可以通過在新建一個對象,然后通過for循環(huán)遍歷來實現(xiàn)拷貝(low)
  • 2.Object.assign(p2,p1); 將p1中屬性和方法拷貝到p2中

在看一下有引用類型的

  • class Person{
        name = "lnj";
        cat = {
            age : 3
        };
        scores = [1, 3, 5];
    }
    let p1 = new Person();
    let p2 = new Object();
    p2.cat = p1.cat;
    
  • 執(zhí)行完上面代碼后會發(fā)生什么

  • 深拷貝下.png

這不就出事了嗎

  • 所以我們需要自定義一個函數(shù)來實現(xiàn)深拷貝,圖示如下

  • function depCopy(target, source) {
        // 1.通過遍歷拿到source中所有的屬性
        for(let key in source){
            // console.log(key);
            // 2.取出當前遍歷到的屬性對應(yīng)的取值
            let sourceValue = source[key];
            // console.log(sourceValue);
            // 3.判斷當前的取值是否是引用數(shù)據(jù)類型
            if(sourceValue instanceof Object){
                // console.log(sourceValue.constructor);
                // console.log(new sourceValue.constructor);
                //這樣如果是object就會創(chuàng)建一個object類型,如果是array類型就會創(chuàng)建一個array類型
                let subTarget = new sourceValue.constructor;
                target[key] = subTarget;
                //遞歸調(diào)用實現(xiàn)拷貝,
                depCopy(subTarget, sourceValue);
            }else{
                target[key] = sourceValue;
            }
        }
    }
    
  • 深拷貝自定義.png

11.數(shù)組高級API

11.1 遍歷對象 forin
  • forin用來遍歷對象,但是對象的屬性是無序的, 所以forin循環(huán)就是專門用于遍歷無序的東西的, 所以不推薦使用forin循環(huán)來遍歷數(shù)組

  • for(let key in obj){    
        console.log(obj[key]);
    }
    
11.2 遍歷數(shù)組
  • 利用Array對象的forEach方法來遍歷數(shù)組

    • forEach方法會自動調(diào)用傳入的函數(shù)

    • 每次調(diào)用都會將當前遍歷到的元素和當前遍歷到的索引和當前被遍歷的數(shù)組傳遞給這個函數(shù)

    • arr.forEach(function (currentValue, currentIndex, currentArray) {
           // console.log(currentValue, currentIndex, currentArray);
            console.log(currentValue);
      });
      //自己來實現(xiàn)一個
       Array.prototype.myForEach = function (fn) {
          // this === [1, 3, 5, 7, 9]
          for(let i = 0; i < this.length; i++){
              fn(this[i], i, this);
          }
      };
      arr.myForEach(function (currentValue, currentIndex, currentArray) {
          console.log(currentValue, currentIndex, currentArray);
      });
      
  • 利用ES6中推出的for of循環(huán)來遍歷數(shù)組

    • for(let value of arr)
11.3數(shù)組的findIndex方法
  • findIndex方法: 定制版的indexOf, 找到返回索引, 找不到返回-1

  • let arr = [3, 2, 6, 7, 6];
    let index = arr.findIndex(function (currentValue, currentIndex, currentArray) {
        // console.log(currentValue, currentIndex, currentArray);
        // if(currentValue === 6){
        if(currentValue === 10){
            return true;
        }
    });
    //自己實現(xiàn)了一個
    rray.prototype.MyfindIndex = function (fn) {
        // this === [1, 3, 5, 7, 9]
        for(let i = 0; i < this.length; i++){
            let re = fn(this[i], i, this);
            if (re === true){
                return i;
            }
            if(i == this.length-1) return  -1;
        }
    };
    
11.4 數(shù)組的find方法
  • find方法返回索引, find方法返回找到的元素,find方法如果找到了就返回找到的元素, 如果找不到就返回undefined

  •  let value = arr.find(function (currentValue, currentIndex, currentArray) {
        // console.log(currentValue, currentIndex, currentArray);
        // if(currentValue === 6){
        if(currentValue === 10){
            return true;
        }
    });
    
11.5 數(shù)組的filter方法
  • 將滿足條件的元素添加到一個新的數(shù)組中

  • let newArray = arr.filter(function (currentValue, currentIndex, currentArray) {
        // console.log(currentValue, currentIndex, currentArray);
        if(currentValue % 2 === 0){ //要滿足的條件
            return true;
        }
    });
    console.log(newArray); // [2, 4]
    //自己實現(xiàn)一下
    Array.prototype.myFilter = function (fn) {
        let newArray = [];
        for(let i = 0; i < this.length; i++){
            let result = fn(this[i], i, this);
            if(result){
                newArray.push(this[i]);
            }
        }
        return newArray;
    }
    
11.6 數(shù)組的map方法(和filter的區(qū)別看一下)
  • 將滿足條件的元素映射到一個新的數(shù)組中(新數(shù)組的長度與原數(shù)組一樣,沒有就返回undefined)

  • let newArray = arr.map(function (currentValue, currentIndex, currentArray) {
        // console.log(currentValue, currentIndex, currentArray);
        if(currentValue % 2 === 0){
            return currentValue;
        }
    });
    console.log(newArray); // [undefined, 2, undefined, 4, undefined]
    //自己實現(xiàn)
     Array.prototype.myMap = function (fn) {
        let newArray = new Array(this.length);
        newArray.fill(undefined);
        for(let i = 0; i < this.length; i++){
            let result = fn(this[i], i, this);
            if(result !== undefined){
                newArray[i] = result;
            }
        }
        return newArray;
    }
    
11.7 刪除數(shù)組元素注意點
  • let len = arr.length;
    for(let i = 0; i < arr.length; i++){
        arr.splice(i,1);
    }
    //刪不干凈,因為每刪一次,數(shù)組中的元素會往前移,導(dǎo)致最后沒法刪了
    //解決辦法,從后往前刪
    for(let i = len - 1; i >= 0; i--){
        // console.log(arr.length); // 5, 4, 3
        // console.log(len);
        arr.splice(i, 1);
    }
    //解決辦法二,采用delete
     for(let i = 0; i < arr.length; i++){
        console.log(arr.length);
        // 注意點: 通過delete來刪除數(shù)組中的元素, 數(shù)組的length屬性不會發(fā)生變化
        delete arr[i];
    }
    
11.8 數(shù)組排序
  • // 如果元素是字符串類型, 那么比較的是字符串的Unicode編碼
    let arr = ["c", "a", "b"];
     arr.sort(function (a, b) {
        if(a > b){
            return -1;
        }else if(a < b){
            return 1;
        }else{
            return 0;
        }
    });
    //如果數(shù)組中的元素是數(shù)值類型
    //如果需要升序排序, 那么就返回a - b;
    //如果需要降序排序, 那么就返回b - a;
    arr.sort(function (a, b) {
        return b - a;
    });
    //按長度排序
     let arr = ["1234", "21", "54321", "123", "6"];
     arr.sort(function (str1, str2) {
         // return str1.length - str2.length; 短的排前面
         return str2.length - str1.length;
     });
    //對象數(shù)組的排序
     let students = [
         {name: "zs", age: 34},
         {name: "ls", age: 18},
         {name: "ww", age: 22},
         {name: "mm", age: 28},
     ];
    students.sort(function (o1, o2) {
        // return o1.age - o2.age;
        return o2.age - o1.age;
    });
    
    

12.字符串操作

在js中字符串可以看做一個特殊的數(shù)組, 所以大部分數(shù)組的屬性/方法字符串都可以使用

  • // 1.獲取字符串長度  .length
     let str = "abcd";
     console.log(str.length);
    
    // 2.獲取某個字符 [索引] / charAt
     let str = "abcd";
     let ch = str[1];//高級瀏覽器才支持 
     let ch = str.charAt(1);
     console.log(ch);
    
    // 3.字符串查找 indexOf / lastIndexOf / includes
     let str = "vavcd";
     let index = str.indexOf("v");
     let index = str.lastIndexOf("v");
     console.log(index);
     let result = str.includes("p");
     console.log(result);  //返回true和false
    
    // 4.拼接字符串 concat / +
     let str1 = "www";
     let str2 = "it666";
     let str = str1 + str2; // 推薦
     let str = str1.concat(str2);
     console.log(str);
    
    // 5.截取子串 slice / substring / substr
    let str = "abcdef";
    let subStr = str.slice(1, 3);
    let subStr = str.substring(1, 3);
    let subStr = str.substr(1, 3);
    console.log(subStr);
    // 6.字符串切割
    let arr = [1, 3, 5];
    let str = arr.join("-");//將數(shù)組換成一個字符串,用-鏈接
     console.log(str);
     let str = "1-3-5";
     let arr = str.split("-");//切割
     console.log(arr);
    
    // 7.判斷是否以指定字符串開頭 ES6
     let str = "http://www.it666.com";
     let result = str.startsWith("www");
     console.log(result);
    // 8.判斷是否以指定字符串結(jié)尾 ES6
    let str = "lnj.jpg";
    let result = str.endsWith("png");
    console.log(result);
    // 4.字符串模板 ES6
    let str = ""; 以前定義字符串
    let str = '';
    let str = `www.it666.com`;//新增定義字符串
    console.log(str);
    console.log(typeof str);
    //以前得通過+拼接
    let str =   "<ul>\n" +
                "    <li>我是第1個li</li>\n" +
                "    <li>我是第2個li</li>\n" +
                "    <li>我是第3個li</li>\n" +
                "</ul>";
    //現(xiàn)在直接寫在``中就行
    let str = `<ul>
                    <li>我是第1個li</li>
                    <li>我是第2個li</li>
                    <li>我是第3個li</li>
                </ul>`;
    
    let name = "lnj";
    let age = 34;
    //以前的拼接方法
    let str = "我的名字是" + name + ",我的年齡是" + age;
    //通過``拼接
    let str = `我的名字是${name},我的年齡是${age}`;
    console.log(str);
    
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怔球,一起剝皮案震驚了整個濱河市聂沙,隨后出現(xiàn)的幾起案子椭微,更是在濱河造成了極大的恐慌,老刑警劉巖浊服,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異季蚂,居然都是意外死亡插龄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門近速,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诈嘿,“玉大人,你說我怎么就攤上這事削葱〗毖牵” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵析砸,是天一觀的道長昔字。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么作郭? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任陨囊,我火速辦了婚禮,結(jié)果婚禮上夹攒,老公的妹妹穿的比我還像新娘蜘醋。我一直安慰自己,他們只是感情好咏尝,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布压语。 她就那樣靜靜地躺著,像睡著了一般编检。 火紅的嫁衣襯著肌膚如雪胎食。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天允懂,我揣著相機與錄音斥季,去河邊找鬼。 笑死累驮,一個胖子當著我的面吹牛酣倾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谤专,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼躁锡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了置侍?” 一聲冷哼從身側(cè)響起映之,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜡坊,沒想到半個月后杠输,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡秕衙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年蠢甲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片据忘。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鹦牛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出勇吊,到底是詐尸還是另有隱情曼追,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布汉规,位于F島的核電站礼殊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晶伦,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一碟狞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧坝辫,春花似錦、人聲如沸射亏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽智润。三九已至及舍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窟绷,已是汗流浹背锯玛。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留兼蜈,地道東北人攘残。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像为狸,于是被迫代替她去往敵國和親歼郭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

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

  • 1. 在ES6之前如何定義一個類?通過構(gòu)造函數(shù)來定義一個類 function Person(myName, ...
    仰望_IT閱讀 203評論 0 1
  • 轉(zhuǎn)載:在開發(fā)中,數(shù)組的使用場景非常多漾根,平日中也涉及到很多數(shù)組的api/相關(guān)操作泰涂,一直也沒有對這塊內(nèi)容進行一塊整理總...
    七色煙火閱讀 3,217評論 0 3
  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,451評論 0 13
  • ECMAScript簡稱就是ES,你可以把它看成是一套標準,JavaScript就是實施了這套標準的一門語言 現(xiàn)在...
    最美時光A閱讀 311評論 0 0
  • *node下用express框架,實現(xiàn)一個簡單的mvc *構(gòu)建工具:gulp / babel / webpack ...
    韓娜愛吃辣_前端程序媛閱讀 1,088評論 0 1