這次帶給大家詳解JS原型和原型鏈以及注意事項有哪些,以下就是實戰案例,一起來看一下。
一.普通物件與函數物件
JavaScript 中,萬物皆物件!但對像也是有差別的。分為普通物件和函數對象,Object 、Function 是 JS 自帶的函數物件。以下舉例說明
var o1 = {}; var o2 =new Object(); var o3 = new f1(); function f1(){}; var f2 = function(){}; var f3 = new Function('str','console.log(str)'); console.log(typeof Object); //function console.log(typeof Function); //function console.log(typeof f1); //function console.log(typeof f2);//function console.log(typeof f3);//function console.log(typeof o1);// object console.log(typeof o2);//object console.log(typeof o3); //object
在上面的例子中 o1 o2 o3 為普通對象,f1 f2 f3 為函數物件。怎麼區分,其實很簡單,凡是透過 new Function() 創建的物件都是函數對象,其他的都是普通對象。 f1,f2,歸根結底都是透過 new Function()的方式進行創建的。 Function Object 也都是透過 New Function()創建的。
一定要分清楚普通對象和函數對象,下面我們會常常用到它。
二. 建構子
##我們先複習一下建構子的知識:function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function() { alert(this.name) } } var person1 = new Person('Zaxlct', 28, 'Software Engineer'); var person2 = new Person('Mick', 23, 'Doctor');
console.log(person1.constructor == Person); //true console.log(person2.constructor == Person); //true
person1 和person2 都是建構子Person 的實例
一個公式:
實例的建構子屬性(constructor)指向建構函數。
三.原型物件
在 JavaScript 中,每當定義物件(函數也是物件)時候,物件中都會包含一些預先定義的屬性。其中每個函數物件都有一個prototype 屬性,這個屬性指向函數的原型物件。 (先用不管什麼是__proto__ 第二節的課程會詳細的剖析)function Person() {} Person.prototype.name = 'Zaxlct'; Person.prototype.age = 28; Person.prototype.job = 'Software Engineer'; Person.prototype.sayName = function() { alert(this.name); } var person1 = new Person(); person1.sayName(); // 'Zaxlct'var person2 = new Person(); person2.sayName(); // 'Zaxlct'console.log(person1.sayName == person2.sayName); //true
我們把上面的例子改一改你就會明白了:
Person.prototype = { name: 'Zaxlct', age: 28, job: 'Software Engineer', sayName: function() { alert(this.name); } }
Person.prototype.constructor == Person
Person.prototype.constructor == Person
##person1 為什麼有constructor 屬性?那是因為 person1 是 Person 的例子。
也就是在Person 建立的時候,建立了一個它的實例物件並賦值給它的prototype,基本流程如下:
var A = new Person();
結論:原型物件(Person.prototype)是建構子(Person)的一個實例。
原型物件其實就是普通物件(但 Function.prototype 除外,它是函數對象,但它很特殊,他沒有prototype屬性(前面說函數物件都有prototype屬性))。看下面的範例:
function Person(){}; console.log(Person.prototype) //Person{} console.log(typeof Person.prototype) //Object console.log(typeof Function.prototype) // Function,这个特殊 console.log(typeof Object.prototype) // Object console.log(typeof Function.prototype.prototype) //undefined
Function.prototype 為什麼是函數物件呢?
var A = new Function (); Function.prototype = A;
上文提到凡是透過 new Function( ) 產生的物件都是函數物件。因為 A 是函數對象,所以Function.prototype 是函數物件。
那原型物件是用來做什麼的呢?主要作用是用於繼承。舉個例子:
var Person = function(name){ this.name = name; // tip: 当函数执行时这个 this 指的是谁? }; Person.prototype.getName = function(){ return this.name; // tip: 当函数执行时这个 this 指的是谁? } var person1 = new person('Mick'); person1.getName(); //Mick
從這個例子可以看出,透過給 Person.prototype 設定了一個函數物件的屬性,那有 Person 的實例(person1)出來的普通物件就繼承了這個屬性。具體是怎麼實現的繼承,就要講到下面的原型鏈了。
小問題,上面兩個 this 都指向誰?
var person1 = new person('Mick'); person1.name = 'Mick'; // 此时 person1 已经有 name 这个属性了 person1.getName(); //Mick
故兩次 this 在函數執行時都指向 person1。
以上是詳解JS原型與原型鏈(一)的詳細內容。更多資訊請關注PHP中文網其他相關文章!