原文:javascript
1.深刻理解javascript原型和閉包——prototype原型html
2.三張圖搞懂JavaScript的原型對象與原型鏈java
打開瀏覽器控制檯,任意定義一個對象,打印出來後,會發現有最後必定有一個默認屬性 「__proto__」,這是 js 的設計思路,相似於 java 中的繼承。瀏覽器
注意:在本章中嚴格區分函數與對象閉包
prototype 與 __proto__
函數
1.區別post
var a = {}; console.log(a.prototype); //undefined console.log(a.__proto__); //Object {} var b = function(){} console.log(b.prototype); //b {} console.log(b.__proto__); //function() {}
2.__proto__ 指向誰?ui
/*一、字面量方式*/ var a = {}; console.log(a.__proto__); //Object {} console.log(a.__proto__ === a.constructor.prototype); //true /*二、構造器方式*/ var A = function(){}; var a = new A(); console.log(a.__proto__); //A {} console.log(a.__proto__ === a.constructor.prototype); //true /*三、Object.create()方式*/ var a1 = {a:1} var a2 = Object.create(a1); console.log(a2.__proto__); //Object {a: 1} console.log(a.__proto__ === a.constructor.prototype); //false(此處即爲圖1中的例外狀況)
3.原型鏈url
var A = function(){}; var a = new A(); console.log(a.__proto__); //A {}(即構造器function A 的原型對象) console.log(a.__proto__.__proto__); //Object {}(即構造器function Object 的原型對象) console.log(a.__proto__.__proto__.__proto__); //null
prototype 屬性
spa
這個prototype的屬性值是一個對象(屬性的集合),默認的只有一個叫作 constructor 的屬性,指向這個函數自己。以下圖:
原型既然做爲對象,屬性的集合,不可能就只弄個constructor來玩玩,確定能夠自定義的增長許多屬性。例如 Object 這個函數,該函數的prototype裏面,就有好幾個其餘屬性。
以上是 Object 的原型示意。
那麼,咱們本身定義的函數/對象中,可不能夠進行自定義內? 答案: 能夠。
function Fn() { } Fn.prototype.name = '王福朋'; Fn.prototype.getYear = function () { return 1988; };
這樣作的意義在哪?
function Fn() { } Fn.prototype.name = '王福朋'; Fn.prototype.getYear = function () { return 1988; }; var fn = new Fn(); console.log(fn.name); // 王福朋 console.log(fn.getYear()); // 1988
首先,定義了個空的 Fn 函數;
接着,自定義 Fn.prototype 屬性;
其次,fn 對象是從 Fn 函數中 new 出來的;
由於每一個對象都有一個隱藏的屬性——「__proto__」,這個屬性引用了建立這個對象的函數的prototype(注意區分對象和函數)。即:fn.__proto__ === Fn.prototype
結論:每一個對象都有一個隱藏的屬性——「__proto__」,這個屬性引用了建立這個對象的函數的prototype(注意區分對象和函數)。