圖解javascript原型&原型鏈

咱們在學習javascript時,常常會聽到「萬物皆對象」,可是呢,其實萬物皆對象的對象也有區別。分爲普通對象和函數對象。
1.對象分爲函數對象和普通對象
    經過new Function()建立的對象都是函數對象,其餘的都是普通對象。
圖片描述javascript

2.構造函數
而提到new關鍵字,咱們不得不提到構造函數。構造函數又分爲自定義構造函數及native構造函數(即構造器)
2.1 自定義構造函數java

function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
    }
    var miya = new Person('miya',18,'engineer'); //miya是構造函數Person的實例;

而實例的構造函數屬性(constructor) 都指向構造函數
    即:miya.constuctor = Person 
    
2.2 構造器 
    js內置的構造器包括Number,Boolean,String,Object,Function,Array,RegExp,Error,Date等
一樣的,咱們的構造器的實例也有一個constuctor指向它的構造器
   函數

let miya= new Array()
    miya.constuctor ==Array;

經過以上的分析,咱們能夠獲得如下這張圖    
圖片描述
這裏擴展一下,其實咱們在作類型判斷的時候習慣用typeof,typeof判斷簡單數據類型的時候實際上是ok的。可是typeof有判斷複雜數據類型不是很清晰,獲得的基本是String或者Function
好比一下圖示判斷
圖片描述
可是,經過上述咱們知道構造器的實例都有一個constructor的屬性指向構造器。那其實咱們直接用constructor即可以清晰地知道這個實例從哪裏來。
圖片描述
3.原型對象
    每一個函數對象都有一個prototype屬性,這個屬性指向函數的原型對象即prototype。
    全部的prototype會有一個默認的constuctor屬性,指向函數對象自己。    學習

function Person(name,age,job){
this.name = name;
    this.age = age;
    this.job = job;
}
Person.prototype.sayName = function () {
    console.log(this.name);
};

let miya = new Person('miya',18,'engineer');
let tiffany = new Person('tiffany',18,'engineer');
miya.sayName();  //miya
tiffany.sayName();  //tiffany
console.log(miya.sayName == tiffany.sayName);  //true
console.log(Person.prototype.constructor == Person);  //true

經過:Person.prototype.constuctor = Person ,由於構造函數的實例是有一個constructor的屬性指向構造函數的,咱們能夠獲得結論其實Person.prototype也是Person的實例
    即:原型對象是構造函數的一個實例【原型對象(Function.prototype除外)是一個普通對象,而不是函數對象】
圖片描述this

4.__proto__屬性
    4.1 JS在建立對象的時候都會有一個__proto__指向它的構造函數的原型對象
圖片描述
其實,每一個對象都有一個__proto__屬性,但只有函數對象有prototype屬性。
所以,能夠獲得如下這樣圖。
圖片描述
    4.2構造函數擴展
  而咱們的構造函數本質上都是從Function new出來的。他們本質上都是Function的一個實例。都有一個__proto屬性指向Function的原型,也有一個constructor屬性指向Function。
圖片描述
    提示:Math,JSON是以對象形式存在的,無需new。他們的__proto__是Object.prototype spa

所以能夠獲得如下的圖示,全部的函數對象的__proto__都指向Function.prototype(是一個空函數)
圖片描述
圖片描述
5.函數對象
    1.全部的構造器都是經過Function new出來的,他們都是Function的實例,他們的__pro__都指向Function.prototype,甚至包括根構造器Object及Function自己。prototype

Number.__proto__ === Function.prototype  // true
Number.constructor == Function //true

String.__proto__ === Function.prototype  // true
String.constructor == Function //true

Object.__proto__ === Function.prototype  // true
Object.constructor == Function // true

Function.__proto__ === Function.prototype // true
Function.constructor == Function //true

    2.除Object.prototype外,全部的構造器的prototype的__proto__屬性都指向Object.prototype3d

Function.prototype.__proto__ === Object.prototype; // true
Number.prototype.__proto__ === Object.prototype; // true
String.prototype.__proto__ === Object.prototype; // true
Array.prototype.__proto__ === Object.prototype; // true
Boolean.prototype.__proto__ === Object.prototype; // true
Object.prototype.__proto__ === Object.prototype; // true

圖片描述
    3.那Object.prototype的__proto__屬性是指向null的。code

Object.prototype.__proto__ === null; // true

圖片描述

    Function.prototype也是惟一一個typeof XXX.prototype爲 function的prototype    
    推導Function.prototype.__proto__是什麼呢? Object.prototype
    全部的構造器都繼承Function.prototype的屬性及方法 =>全部的構造器函數都是普通的js函數能夠用Object的方法
    Object.prototype.__proto__ == null
 
 對象

console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype)   // object
console.log(typeof Number.prototype)   // object
console.log(typeof Boolean.prototype)  // object
console.log(typeof String.prototype)   // object
console.log(typeof Array.prototype)    // object
console.log(typeof RegExp.prototype)   // object
console.log(typeof Error.prototype)    // object
console.log(typeof Date.prototype)     // object
console.log(typeof Object.prototype)   // object

 
補充:
    null是一個獨立數據類型,而不是一個空引用,只是指望此處引用一個對象 https://developer.mozilla.org...    typeof null == Object是一個遺留bug

相關文章
相關標籤/搜索