function Demo(){};
let d1 = new Demo;
複製代碼
用來初始化新建立的對象的函數是構造函數。在上面代碼中,Demo()函數是構造函數bash
function Demo(){};
let d1 = new Demo;
複製代碼
經過構造函數的new操做建立的對象是實例對象。能夠用一個構造函數,構造多個實例對象,在上面代碼中d1就是實例對象函數
function Demo(){};
Demo.prototype.a = 666;
let d1 = new Demo;
let d2 = new Demo;
console.log(Demo.prototype.a); //666
console.log(d1.a); //666
console.log(d2.a); //666
複製代碼
Demo.prototype,指的就是原型對象。經過同一個構造函數實例化的多個對象具備相同的原型對象。因此常常使用原型對象來實現繼承,Object.prototype的原型對象是nullui
原型對象有一個constructor屬性,指向該原型對象對應的構造函數spa
function Demo(){};
console.log(Demo.prototype.constructor === Demo);//true
複製代碼
因爲實例對象能夠繼承原型對象的屬性,因此實例對象也擁有constructor屬性,而且實例對象的constructor也指向原型對象對應的構造函數prototype
function Demo(){};
let d1 = new Demo;
console.log(d1.constructor === Demo); //true
複製代碼
實例對象有一個proto屬性,指向該實例對象對應的原型對象code
function Demo(){};
let d1 = new Demo;
console.log(d1.__proto__ === Demo.prototype);//true
複製代碼
function Demo(){};
var d1 = new Demo;
console.log(Demo.prototype.__proto__ === Object.prototype);//true
console.log(Demo.prototype.constructor === Object);//true
複製代碼
Demo.prototype是d1的原型對象同時他也能夠稱做爲實例對象,那麼做爲實例對象它又是怎麼來的了?它的原型對象又是什麼。實際上,任何對象均可以看作是經過Object()構造函數的new操做實例化的對象,因此,Demo.prototype做爲實例對象,它的構造函數是Object(),原型對象是Object.prototype。相應地,構造函數Object()的prototype屬性指向原型對象Object.prototype;實例對象Demo.prototype的proto屬性一樣指向原型對象Object.prototype,實例對象Demo.prototype自己具備constructor屬性,因此它會覆蓋繼承自原型對象Object.prototype的constructor屬性cdn
Object.prototype也可做爲實例對象,那麼Object.prototype. __ proto __又指向什麼了?結果爲null, 這也就是到了原型鏈的盡頭啦對象
console.log(Object.prototype.__proto__ === null);//true
複製代碼
先明白一個概念函數也是對象,任何函數均可以看作是經過Function()構造函數的new操做實例化的結果, 若是把函數Demo當成實例對象的話,其構造函數是Function(),其原型對象是Function.prototype;相似地,函數Object的構造函數也是Function(),其原型對象是Function.prototypeblog
functionDemo(){};
var f1 = new Demo();
console.log(Demo.__proto__ === Function.prototype);//true
console.log(Object.__proto__ === Function.prototype);//true
複製代碼
那麼問題又來了,Function 做爲實例對象他的proto又是什麼了?其實 全部的函數均可以當作是構造函數Function()的new操做的實例化對象因此,若是Function做爲實例對象,其構造函數是Function,其原型對象是Function.prototype繼承