普通對象與函數(shù)對象
在javascript中萬物皆對象,但對象是有區(qū)別的回俐,分為普通對象和函數(shù)對象吹艇,那怎么區(qū)分呢,凡是通過 new Function() 創(chuàng)建的對象都是函數(shù)對象钮蛛,其他的都是普通對象鞭缭,Object和Function都是JS自帶的函數(shù)對象,都是通過new Function()創(chuàng)建的魏颓×肜保看下面的例子:
function f1(){};
console.log(f1.prototype) //f1{}
console.log(typeof f1. prototype) //Object
console.log(typeof Function.prototype) // Function,這個特殊
console.log(typeof Object.prototype) //Object
console.log(typeof Function.prototype.prototype) //undefined
prototype和proto的概念
prototype是函數(shù)的一個屬性(每個函數(shù)都有一個prototype屬性)甸饱,這個屬性是一個指針沦童,指向一個對象。它是顯示對象的原型的屬性叹话。
__proto__是一個對象擁有的內置屬性(請注意:prototype是函數(shù)的內置屬性偷遗,__proto__是對象的內置屬性),是JS內部使用尋找原型鏈的屬性渣刷。
怎么理解呢鹦肿?
簡單點說,就是對象屬性的修改和獲取通過prototype來實現(xiàn)辅柴,而對象屬性的繼承通過__proto__來實現(xiàn)
new的過程
var Person = function(){};
var p = new Person();
new的過程拆分成以下三步:
(1) var p={}; // 初始化一個對象p
(2) p.\_\_proto\_\_ = Person.prototype;
(3) Person.call(p); // 構造p箩溃,也可以稱之為初始化p
總結
1.原型和原型鏈是JS實現(xiàn)繼承的一種模型。
2.原型鏈的形成是真正是靠__proto__ 而非prototype
要深入理解這兩句話碌嘀,我們舉個例子:
var animal = function(){};
var dog = function(){};
animal.price = 2000;//
dog.prototype = animal;
var tidy = new dog();
console.log(dog.price) // undefined
console.log(tidy.price) // 2000為什么呢涣旨?
畫一下內存圖:
這說明什么問題呢,執(zhí)行dog.price的時候股冗,發(fā)現(xiàn)沒有price這個屬性霹陡,雖然prototype指向的animal有這個屬性,但它并沒有去沿著這個“鏈”去尋找。同樣烹棉,執(zhí)行tidy.price的時候攒霹,也沒有這個屬性,但是__proto__指向了animal浆洗,它會沿著這個鏈去尋找催束,animal中有price屬性,所以tidy.price輸出2000伏社。由此得出抠刺,原型鏈的真正形成是靠的__proto__,而不是prototype摘昌。
因此速妖,如果在這樣指定dog.__proto__ = animal,那dog.price = 2000聪黎。