重學前端學習筆記(八)--JavaScript中的原型和類

筆記說明

重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄, 天天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完整的能夠加入winter的專欄學習【原文有winter的語音】,若有侵權請聯繫我,郵箱:kaimo313@foxmail.com。

1、什麼是原型?

1.0、定義

原型是指一個詞語或一個類型意義的全部典型模型或原形象,是一個類型的組典型特徵

1.一、基於類的編程語言

諸如 C++、Java 等流行的編程語言是使用類的方式來描述對象, 基於類的編程提倡使用一個關注分類和類之間關係開發模型。

1.二、基於原型的編程語言

如 JavaScript 編程語言是利用原型來描述對象, 基於原型的編程看起來更爲提倡程序員去關注一系列對象實例的行爲,然後纔去關心如何將這些對象,劃分到最近的使用方式類似的原型對象,而不是將它們分紅類。

1.三、原型系統的「複製操做」有兩種實現思路

  • 一個是並不真的去複製一個原型對象,而是使得新對象持有一個原型的引用
  • 另外一個是切實地複製對象,今後兩個對象再無關聯。

javaScript選擇了第一種方式。前端

2、JavaScript 的原型

2.0、原型系統的兩條歸納

  • 若是全部對象都有私有字段 [[prototype]],就是對象的原型
  • 讀一個屬性,若是對象自己沒有,則會繼續訪問對象的原型,直到原型爲空或者找到爲止。

2.一、三個內置函數

能夠利用下面三個方法,更直接地訪問操縱原型,來實現抽象和複用。java

  • Object.create 根據指定的原型建立新對象,原型能夠是 null
  • Object.getPrototypeOf 得到一個對象的原型
  • Object.setPrototypeOf 設置一個對象的原型

winter舉了用原型來抽象貓和虎的例子:程序員

var cat = {
    say() {
        console.log("meow~");
    },
    jump() {
        console.log("jump");
    }
}

var tiger = Object.create(cat,  {
    say: {
        writable: true,
        configurable: true,
        enumerable: true,
        value: function(){
            console.log("roar!");
        }
    }
})


var anotherCat = Object.create(cat);

anotherCat.say(); // meow~

var anotherTiger = Object.create(tiger);

anotherTiger.say(); // roar!

3、早期版本中的類與原型

3.0、「類」的定義是一個私有屬性 [[class]]

全部具備內置 class 屬性的對象:(ES3和以前版本)編程

var o = new Object;
var n = new Number;
var s = new String;
var b = new Boolean;
var d = new Date;
var arg = function(){ return arguments }();
var r = new RegExp;
var f = new Function;
var arr = new Array;
var e = new Error;
console.log(
    [o, n, s, b, d, arg, r, f, arr, e].map(v =>   Object.prototype.toString.call(v)
  )
)

語言使用者惟一能夠訪問 [[class]] 屬性的方式是 Object.prototype.toString編程語言

3.一、[[class]] 私有屬性被 Symbol.toStringTag 代替

能夠查看MDN文檔Symbol.toStringTag以及Object.prototype.toString的介紹:(ES5開始)函數

var o = { [Symbol.toStringTag]: "MyObject" }
console.log(o + ""); // [object MyObject]

上面這段代碼建立了一個新對象,而且給它惟一的一個屬性 Symbol.toStringTag,用字符串加法觸發了Object.prototype.toString 的調用,發現這個屬性最終對 Object.prototype.toString 的結果產生了影響。學習

3.二、new運算作了什麼?

  • 一、以構造器的 prototype 屬性(注意與私有字段 [[prototype]] 的區分)爲原型,建立新對象
  • 二、將 this 和調用參數傳給構造器,執行
  • 三、若是構造器返回的是對象,則返回,不然返回第一步建立的對象。

用構造器模擬類的兩種方法:this

// 一、在構造器中修改 this,給 this 添加屬性

function c1() {
    this.p1 = 1;
    this.p2 = function(){
        console.log(this.p1);
    }
}
var o1 = new c1;
o1.p2(); // 1

// 二、修改構造器的 prototype 屬性指向的對象,它是從這個構造器構造出來的全部對象的原型。

function c2() {
}
c2.prototype.p1 = 1;
c2.prototype.p2 = function() {
    console.log(this.p1);
}

var o2 = new c2;
o2.p2(); // 1

4、ES6 中的類

4.0、類的基本寫法

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  // Getter
  get area() {
    return this.calcArea();
  }
  // Method
  calcArea() {
    return this.height * this.width;
  }
}

4.一、類的繼承能力

class Animal {
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(this.name + ' makes a noise.');
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name); // call the super class constructor and pass in the name parameter
  }

  speak() {
    console.log(this.name + ' barks.');
  }
}

let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.

上面代碼調用子類的 speak 方法獲取了父類的 name。若是對於class還想了解更多,能夠查看MDN文檔Classes部分。prototype

我的總結

其實對於這一部分非常不明白,也不清楚,對於這些js基礎性的東西仍是要多下下功夫才行,畢竟winter的重學前端真心不錯,對我來講進行查漏補缺,看清本身的水平頗有幫助,路還很長,還要加油呀!!!code

相關文章
相關標籤/搜索