原型鏈、繼承 和 instanceof

原型鏈、繼承 和 instanceof

參考:
MDN:instanceof
MDN:Inheritance and the prototype chain
理解JavaScript的原型鏈和繼承javascript

new實現了什麼操做

new的過程發生了什麼?html

function A(name){
  this.name = name
}
var a = new A('hehe')

 // var a = new A('hehe') =>
 var a = new Object();
 a.__proto__ = A.prototype; 
 A.call(a, 'hehe');

原型鏈和prototype屬性

原型鏈是什麼

上面的 __proto__ 是什麼?
就是原型鏈,原型鏈是內部 [ [Prototype ]],指向它「父類」的prototype。java

打開瀏覽器控制檯,能夠看到函數變量都有一個prototype屬性(箭頭函數沒有)。
經過這一句a.__proto__ = A.prototype; 說明a的原型鏈就是指向函數A的prototype屬性。瀏覽器

這裏就有一個重要的認識了,雖然名字很像,可是原型鏈並非prototype屬性,同時原型鏈指向「父類」的prototype。幾乎全部對象都有原型鏈(除了null和undefined),經過__proto__ 能夠看到原型鏈指向什麼(固然最好使用 Object.getPrototypeOf 取原型鏈)babel

經過實驗能夠發現,js中對象的鏈能夠很是複雜。
一圖勝千言。這裏借一張圖。
enter image description hereapp

簡而言之函數

  • 函數對象,Function,Object,Array等等的原型鏈都指向Function.prototype網站

  • 經過new操做符建立的對象原型鏈指向原來的函數的prototype屬性this

  • Object.prototype屬性的原型鏈指向null(到null就中止了)spa

  • 而Function.prototype(Array,Date,String等等),以及函數對象的prototype,原型鏈都指向Object.prototype

prototype屬性到底是什麼呢

能夠看到是一個Object,有constructor和原型鏈。constructor是一個函數,也就是函數自身。這能夠爲後面提到的繼承作準備。

instanceof什麼意思

The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.

Syntax:
object instanceof constructor

意思就是object.__proto__===constructor.prototype

MDN的教程中舉例

// defining constructors
function C() {}
var o = new C();
// true, because: Object.getPrototypeOf(o) === C.prototype
o instanceof C;

可是

var simpleStr = 'This is a simple string'; 
var myString  = new String();

simpleStr instanceof String; // returns false, checks the prototype chain, finds undefined

但是在瀏覽器中試驗Object.getPrototypeOf(simpleStr) === String.prototype
結果是true,大概這算做一個特殊狀況

如何實現繼承

https://babeljs.io/repl/
能夠在這個網站在線編譯並查看結果

class A{
  constructor(name) {
    this.name= name
  }
  toString() {
    return this.name
  }
}
class B extends A {
  toString(){
    return this.name + 'b'
  }
}

編譯出來的ES5繼承

function _inherits(subClass, superClass) { 
    subClass.prototype.__proto__=superClass.prototype;
}
var A = (function () {
    function A(name) {
        this.name = name;
    }
    A.prototype.toString = function toString() {
        return this.name;
    };
    return A;
})();
var B = (function (_A) {
    function B() {
        if (_A != null) {
            _A.apply(this, arguments);
        }
    }
    _inherits(B, _A);
    B.prototype.toString = function toString() {
        return this.name + 'b';
    };
    return B;
})(A);

簡單來講就是這樣

相關文章
相關標籤/搜索