通過面試的挫折以後,繼續深刻學習~~面試
傳統的構造函數對象包含方法時,在構造函數建立時,就會將全部內容從新建立一次,致使數據的重複,代碼的冗餘,以下所示: function Person(name, age) { this.name = name; this.age = age; this.sayHello = function () { console.log("Hello"); } } var p1 = new Person(); var p2 = new Person(); p1.sayHello === p2.sayHello // 結果爲false,由於p1,和p2的sayHello雖結構同樣,但倒是兩個不一樣的對象
改良1:將方法提取到外面框架
function sayHello(){ console.log("Hello"); } function Person(name, age) { this.name = name; this.age = age; this.sayHello = sayHello; } var p1 = new Person(); var p2 = new Person(); p1.sayHello === p2.sayHello // 結果爲true,但當代碼量不斷增長,自定義的函數愈來愈多時,可能會和框架中的函數發生命名衝突,也不利於代碼的維護
改良2:將方法放到構造函數中,且避免命名衝突,原型概念出現函數
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function (){ console.log("Hello"); } var p1 = new Person(); var p2 = new Person(); p1.sayHello === p2.sayHello // 結果爲true
構造函數一旦被建立,就會有一個原型屬性,也是個對象,能夠往裏面添加成員,每一個由構造函數建立出來的對象都會默認鏈接到原型屬性上去。學習
當js引擎查找對象屬性時,會先查找對象上是否具備該屬性,若是沒有,就會去原型屬性上去查找。this
因此,什麼是原型?原型是可以實現繼承的,當構造函數被定義的時候,原型也就被建立出來,它能夠存儲屬性和方法,既是一個屬性也是一個對象。當構造函數建立的實例對象須要訪問某個方法或屬性,而這個對象又沒有該方法或屬性的時候,它會去原型上面去查找。也就是實例對象訪問原型對象的屬性或調用原型對象的方法,說的通俗一點也就是把別的對象的方法或屬性拿過來本身用,就是繼承,因此咱們也能夠說對象繼承自其原型。prototype
引入:屬性查找機制:對象在訪問屬性或方法時,首先在當前對象查找,若是該對象有該屬性或方法,則中止查找,若是沒有,則去原型中查找,若是原型沒有,則去原型的原型中查找,直到原型的頂部,若是仍是沒有,則返回undefined(屬性)或 xxx is not a function(方法)調試
構造函數建立出來的對象(實例對象)繼承構造函數的原型屬性和原型對象code
經過 proto 容許實例對象直接訪問原型,一般用於在調試中查看原型的成員(實例對象不容許修改原型)對象
有一個默認屬性:constructor => 構造器,表示該原型是與什麼構造函數聯繫起來的
∴ 構造函數經過 prototype 的屬性訪問原型,原型能夠經過 constructor 訪問構造函數繼承
該概念由其餘面向對象的語言引入。