咱們在學習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