JavaScript的原型鏈一直是個我搞不懂的東西。包括我在寫文章和畫關(guān)系圖的時候。
不知道是什么歷史原因讓js產(chǎn)生了如此復雜的繼承關(guān)系。
記得以前玩游戲,有個技能叫:死亡纏繞。來形容這個很貼切。
直接上圖,有問題歡迎指正!

js原型鏈.png
畫圖是明確問題的很好方式,畫了一遍圖之后,清晰了不少。
總結(jié)點規(guī)律:
- 所有對象都在原型鏈上
- 除了null 每個對象都有且唯一的proto原型對象,即僅有一條原型鏈
- 只能訪問原型鏈上的方法和屬性
- f 由F new操作而來,看似他們關(guān)系很密切 ,其實f和F的原型鏈半毛錢關(guān)系沒有,即F原型鏈上的方法屬性f均不能訪問。
new操作符到底做了什么?
以如下new操作為例:
function F(name) {
this.name = name;
}
const f = new F("test")
- 創(chuàng)建一個新對象
let instance = new Object();
- 創(chuàng)建instance原型鏈
instance.__proto__ = F.prototype;
- 在instance中執(zhí)行F函數(shù)體
F.call(instance)
- 判斷執(zhí)行結(jié)果類型,如果為基礎(chǔ)數(shù)據(jù)類型(undefined, null, number, string, Boolean)則返回instance,反之,則返回該對象
自己手動實現(xiàn)一個 newFunc:
function newFunc(func){
var instance = new Object();
if (func.prototype !== null) {
instance.__proto__ = func.prototype;
}
var result = func.apply(instance);
if ((typeof result === "object" || typeof result === "function") && result !== null)
{
return result;
}
return instance;
}
//測試
function F(){
this.a = "hahah"
}
let f = newFunc(F);//F {a: "hahah"}
關(guān)于最后一條可能不好理解,上幾個例子:
function Person1(name) {
this.name = name;
}
function Person2(name) {
this.name = name;
return this.name;
}
function Person3(name) {
this.name = name;
return new Array();
}
function Person4(name) {
this.name = name;
return "hahah";
}
function Person5(name) {
this.name = name;
return function() {};
}
function Person6(name) {
this.name = name;
return String(1);
}
var person1 = new Person1('person1'); // 函數(shù)無返回,默認返回undefined{name: 'person1'}
var person2 = new Person2('person2'); // {name: 'person2'}
var person3 = new Person3('person3'); // []
var person4 = new Person4('person4'); // 'person4'
var person5 = new Person5('person5'); // function() {}
var person6 = new Person6('person6'); // name: "person6"