__proto__
和prototype是原生js中比較重要的一環,接下來我從函數和對象,兩個方面,談談個人理解編程
js函數是原生js比較重要的一環,先來談談我對函數的理解,微信
js是函數式編程,最重要的就是prototype
和constructor
函數式編程
首先明確一點,每一個函數都有prototype屬性,prototype指向了一個對象,這個對象就叫原型對象。函數
每一個原型對象有一個constructor屬性,指向了構造函數自己,spa
光說仍是有點難懂,我先上圖prototype
// 代碼 function foo() {} // 原型 console.log(foo.prototype); // {constructor: ƒ} // 構造器 console.log(foo.prototype.constructor); // ƒ foo() {}
上面代碼和圖可知foo的prototype
屬性指向一個對象,而後對象有一個屬性constructor 又指向了 foo構造函數,看下圖:3d
就是這樣的關係,不過這個不能單獨理解,且聽我下面講完__proto__
屬性code
__proto__
屬性每一個對象都有__proto__
屬性指向構造函數的prototype屬性;對象
怎麼驗證呢?blog
這裏首先要先說下建立對象的三種方式了
一、對象字面量(經常使用)
var _obj = {};
二、構造函數Object
var _obj = new Object();
三、經過Object.create(prototype) 初始化對象;
var _o = {}; var _obj = Object.create(_o);
而後 其實這三種方式都調用了Object函數,生成的對象的__proto__
屬性,都指向了Object函數的prototype屬性
var _obj = {}; console.log(_obj); // _obj.__proto__ 指向了Object的原型對象{……} console.log(_obj.__proto__ === Object.prototype); // true
這樣咱們驗證出來全部對象都有__proto__
屬性,指向了構造函數的原型對象
而後對象的__proto__
和函數的prototype
有什麼關係呢?
實例化對象驗證
咱們都知道實例化會生成一個對象,對象都有__proto__
屬性,指向原型對象,
那就意味着函數的prototype屬性,和實例化的__proto__
指向同一個對象,驗證下。
// 一、__proto__指向的是【構造函數的prototype屬性】 function fnxx(){} // new生成一個實例對象 var _xx = new fnxx(); // 對象的__proto__和函數的prototype console.log(_xx.__proto__ === fnxx.prototype); // true
上面代碼跑了以後,結果爲true,說明我們驗證是正確的😄!
而後這有什麼用呢?
看下面
js在建立對象的時候都有__proto__
內置屬性,用於指向建立它函數對象的原形對象prototype
沒錯這就是原型鏈。
_xx.__proto__.__proto_
…… 沿着__proto__
屬性逐層向下查找,這就是一個最簡單的原型鏈,繼承的話也是這樣一層層向下找。
js中萬物皆對象,Function也是對象,全部對象指向了Object對象 ,也就是說Object對象是全部對象的基類;
Object的__proto__
屬性指向null;
驗證下
function fnxx(){} // 二、對象的__proto__ console.log(fnxx.prototype.__proto__); // 指向Object構造函數的原型對象 console.log(fnxx.prototype.__proto__ === Object.prototype); // true // Object對象是全部js對象的基類 console.log(Object.prototype.__proto__); // null
至此一個完整的鏈條就很清晰了;
函數都有一個prototype屬性,指向原型對象,原型對象有constructor 屬性,指向了構造函數自己。
對象有__proto__
屬性,指向建立它的原型對象,__proto__
用來實現原型鏈查找,是繼承中關鍵的一環。
js中最重要的兩個概念__proto__
和prototype這裏就講清楚了,你們有啥不懂的,能夠評論留言。
接下來我再出幾篇,關於繼承,還有prototype原型模式的應用。