深入理解javascript原型和閉包
函式就是物件的一種,因為通過instanceof函式可以判斷。函式就是物件的一種,因為通過instanceof函式可以判斷。
var fn = function () { };
console.log(fn instanceof Object); // true
對!函式是一種物件,但是函式卻不像陣列一樣——你可以說陣列是物件的一種,因為陣列就像是物件的一個子集一樣。但是函式與物件之間,卻不僅僅是一種包含和被包含的關係,函式和物件之間的關係比較複雜,甚至有一點雞生蛋蛋生雞的邏輯,咱們這一節就縷一縷。
function Fn() { this.name = '王福朋'; this.year = 1988; } var fn1 = new Fn();
上面的這個例子很簡單,它能說明:物件可以通過函式來建立。對!也只能說明這一點。
但是我要說——物件都是通過函式建立的——有些人可能反駁:不對!因為:
var obj = { a: 10, b: 20 };
var arr = [5, 'x', true];
但是這只是建立物件的一種快捷方式,其內部依然會通過new Object() 去建立 所以,可以很負責任的說——物件都是通過函式來建立的。
現在是不是糊塗了—— 物件是函式建立的,而函式卻又是一種物件——天哪!函式和物件到底是什麼關係啊?
下面我們要去了解一下prototype原型物件函式也是一種物件。他也是屬性的集合,你也可以對函式進行自定義屬性。
不用等咱們去試驗,javascript自己就先做了表率,人家就預設的給函式一個屬性——prototype。對,每個函式都有一個屬性叫做prototype。---函式原型物件
這個prototype的屬性指向一個物件,就是原型物件,預設有一個constructor 屬性指向建構函式
function Fn() {} Fn.prototype.name = 'zhangsan'; Fn.prototype.getName = function () { return name; } var f1 = new Fn() console.log(f1)
每個物件都有一個隱藏的屬性——“__proto__”,這個屬性引用了建立這個物件的函式的prototype。
這個__proto__是一個隱藏的屬性,javascript不希望開發者用到這個屬性值,有的低版本瀏覽器甚至不支援這個屬性值。所以你在Visual Studio 2012這樣很高階很智慧的編輯器中,都不會有__proto__的智慧提示,但是你不用管它,直接寫出來就是了。
每個物件都有一個__proto__屬性,指向建立該物件的函式的prototype。
自定義函式的prototype本質上就是和var obj = {} 是一樣的,都是被Object建立,所以它的__proto__指向的就是Object.prototype。