# 個人理解
原型:
prototype首先是只作用於函數的屬性,無法直接用於對象或變量。
每個函數中都自帶一個__proto__屬性(可以存儲繼承對象中的prototype屬性--- p.__proto__ = Person.prototype)。
在實例化對象(構造函數)時,尋找某個屬性(如demo中的name屬性),在當前屬性中無法找到屬性,會從xxx.__proto__中進行尋找。若還未找到,會繼續向xxx.__proto__.__proto__ 中進行尋找。
** 實例化(創建對象)相當於利用.call()屬性修改this的作用域。 如var p = new Person() 相當於 p --> Person.call(p)
1 // demo1 --- 原型 2 var Person = function () { } 3 Person.prototype = { 4 name: "zhangsan" 5 } 6 var p = new Person(); 7 console.log(p);
結構如下圖

原型鏈:
在實例化對象(構造函數)時,尋找某個屬性(如demo中的name屬性),在當前屬性中無法找到屬性,會從xxx.__proto__中進行尋找。若還未找到,會繼續向xxx.__proto__.__proto__ 中進行尋找。
利用上述原理,可通過繼承方法(如demo2,Programmer函數中的prototype繼承於Person中的屬性),使子繼承於父對象中的屬性,若存在同名屬性,則取子對象中的值。
原型鏈其實就是通過__proto__屬性,以層層遞推的方式,一層一層的尋找需要的屬性。
1 // demo2 --- 原型鏈 2 var Person = function () { } 3 Person.prototype.gongzi = 5000; 4 Person.prototype.say = function () { 5 console.log("天氣很好") 6 } 7 var Programmer = function () {} 8 Programmer.prototype = new Person() 9 Programmer.prototype.gongzi = 15000; 10 Programmer.prototype.wcd = function () { 11 console.log("天氣也很好") 12 } 13 var p = new Programmer() 14 console.log(p)
結構如下圖

原型繼承:
通過原型鏈理論,利用 son.prototype = new Father() 等方式,可讓子對象繼承父對象中屬性。
在查找屬性時,會先從子對象中尋找需要的屬性,如未找到,則會在__proto__這個隱藏屬性中尋找。而我們又通過prototype繼承了父對象中需要的屬性,所以會在__proto__中看到繼承自父對象的屬性。
1 // demo3 --- 原型鏈繼承 2 function Person(name, age) { 3 this.name = name; 4 this.age = age; 5 } 6 Person.prototype.sayHello = function () { 7 console.log("名字叫 " + this.name) 8 } 9 function Student() {} 10 Student.prototype = new Person('zhangsan',18);//此步驟為繼承 父 中的屬性 11 Student.prototype.grade = 3; 12 Student.prototype.test = function(){ 13 console.log(this.grade); 14 } 15 var s = new Student(); 16 console.log(s);
結構如下圖
這就是我認為的原型鏈繼承的根本思想。