對於不少前端開發者而言,JavaScript中原型與原型鏈是一個比較容易疑惑的點,因此本文記錄了本身對應這方面的一點理解,之後有更深的理解再來更新。前端
想要了解原型與原型鏈,首先要了解什麼是對象?面向對象編程(Object Oriented Programming,縮寫爲 OOP)是目前主流的編程範式,即把實際上各類複雜關係抽象爲多個對象後對它們進行分工合做從而完成對現實環境的模擬。所以對象是單個實物的抽象,抽象所得的對象是一個容器,擁有屬性(property)和方法(method)。例如,咱們把學生抽象爲student對象,那麼屬性就能夠用來記錄具體是哪個年級的學生(如初1、高一等),用方法來表示學生的某種行爲(如學習、玩耍等)。編程
當咱們想要使用面向對象編程時,首要任務是生成對象。在JavaScript中,構造函數(constructor)就是專門用來生成實例對象的。一個構造函數,能夠生成多個實例對象,這些實例對象都有相同的結構。函數
var Student= function () { this.age= 18; }; var s = new Student(); s.age// 18
特別須要注意的是:學習
除了用new命令生成新的實例對象,咱們還能夠經過Object.create() 來建立,這種方法適用於咱們沒有辦法拿到構造函數而只能拿到一個現有的對象。this
var student1 = { name:'Solar', age:18, greeting:function(){ console.log('Hello!'); } }; var student2 = Object.create(student1); student2.name//Solar student2.greeting()//Hello!
上面代碼中,Object.create方法以student1對象爲原型,生成了student2對象。student2繼承了student1的全部屬性和方法。prototype
首先讓咱們來了解一下爲何會有原型對象(prototype)?code
function Student(name, age) { this.name = name; this.age = age; this.greeting = function(){ console.log('Hello!'); } } var student1= new Student('Solar', '18'); var student2 = new Student('Moonbyul', '17'); student1.greeting=== student2.greeting // false
從以上代碼能夠看到,經過構造函數實例出的對象,雖然都具備greeting方法,可是由於這個方法是生成在自身的每一個實例對象上,也就是每生成一個實例就會新建一個greeting方法。可是其實greeting方法都是一樣的,沒有必要屢次生成形成資源浪費,因而JavaScript的原型對象就誕生了。JavaScript規定,每一個函數都有一個prototype屬性,指向一個對象。對象
function Animal(name) { this.name = name; } Animal.prototype.color = 'white'; var cat1 = new Animal('大毛'); var cat2 = new Animal('二毛'); cat1.color // 'white' cat2.color // 'white'
上面代碼中,構造函數Animal的prototype屬性,就是實例對象cat1和cat2的原型對象。原型對象上添加一個color屬性,結果,實例對象都共享了該屬性。繼承
原型對象的屬性不是實例對象自身的屬性。只要修改原型對象,變更就馬上會體如今全部實例對象上。ip
Animal.prototype.color = 'yellow'; cat1.color // "yellow" cat2.color // "yellow"
若是實例對象自身就有某個屬性或方法,它就不會再去原型對象尋找這個屬性或方法。
cat1.color = 'black'; cat1.color // 'black' cat2.color // 'yellow' Animal.prototype.color // 'yellow';
JavaScript 規定,全部對象都有本身的原型對象(prototype)。一方面,任何一個對象,均可以充當其餘對象的原型;另外一方面,因爲原型對象也是對象,因此它也有本身的原型。所以,就會造成一個「原型鏈」(prototype chain):對象到原型,再到原型的原型……
若是一層層地上溯,全部對象的原型最終均可以上溯到Object.prototype,即Object構造函數的prototype屬性。也就是說,全部對象都繼承了Object.prototype的屬性。Object.prototype的原型是null。null沒有任何屬性和方法,也沒有本身的原型。所以,原型鏈的盡頭就是null。