這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1. 對原型、原型鏈的理解 在JavaScript中是使用構造函數來新建一個對象的,每一個構造函數的內部都有一個 prototype 屬性,它的屬性值是一個對象,這個對象包含了可以由該構造函數的所有實例共用的屬性和方法。當使用構造函數新建 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
1. 對原型、原型鏈的理解
在JavaScript中是使用構造函數來新建一個對象的,每一個構造函數的內部都有一個 prototype 屬性,它的屬性值是一個對象,這個對象包含了可以由該構造函數的所有實例共用的屬性和方法。當使用構造函數新建一個對象後,在這個對象的內部將包含一個指針,這個指針指向構造函數的 prototype 屬性對應的值,在 ES5 中這個指針被稱為對象的原型。一般來說不應該能夠獲取到這個值的,但是現在瀏覽器中都實現了 __proto__ 屬性來訪問這個屬性,但是最好不要使用這個屬性,因為它不是規範中規定的。ES5 中新增了一個 Object.getPrototypeOf() 方法,可以通過這個方法來獲取對象的原型。
當訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那麼它就會去它的原型對象里找這個屬性,這個原型對象又會有自己的原型,於是就這樣一直找下去,也就是原型鏈的概念。原型鏈的盡頭一般來說都是 Object.prototype 所以這就是新建的對象為什麼能夠使用 toString() 等方法的原因。
特點:JavaScript 對象是通過引用來傳遞的,創建的每個新對象實體中並沒有一份屬於自己的原型副本。當修改原型時,與之相關的對象也會繼承這一改變。
2. 原型修改、重寫
function Person(name) { this.name = name } // 修改原型 Person.prototype.getName = function() {} var p = new Person('hello') console.log(p.__proto__ === Person.prototype) // true console.log(p.__proto__ === p.constructor.prototype) // true // 重寫原型 Person.prototype = { getName: function() {} } var p = new Person('hello') console.log(p.__proto__ === Person.prototype) // true console.log(p.__proto__ === p.constructor.prototype) // false
可以看到修改原型的時候p的構造函數不是指向Person了,因為直接給Person的原型對象直接用對象賦值時,它的構造函數指向的了根構造函數Object,所以這時候p.constructor === Object
,而不是p.constructor === Person
。要想成立,就要用constructor指回來:
Person.prototype = { getName: function() {} } var p = new Person('hello') p.constructor = Person console.log(p.__proto__ === Person.prototype) // true console.log(p.__proto__ === p.constructor.prototype) // true
3. 原型鏈指向
p.__proto__ // Person.prototype Person.prototype.__proto__ // Object.prototype p.__proto__.__proto__ //Object.prototype p.__proto__.constructor.prototype.__proto__ // Object.prototype Person.prototype.constructor.prototype.__proto__ // Object.prototype p1.__proto__.constructor // Person Person.prototype.constructor // Person
4. 原型鏈的終點是什麼?如何列印出原型鏈的終點?
由於Object
是構造函數,原型鏈終點是Object.prototype.__proto__
,而Object.prototype.__proto__=== null // true
,所以,原型鏈的終點是null
。原型鏈上的所有原型都是對象,所有的對象最終都是由Object
構造的,而Object.prototype
的下一級是Object.prototype.__proto__
。
5. 如何獲得對象非原型鏈上的屬性?
使用後hasOwnProperty()
方法來判斷屬性是否屬於原型鏈的屬性:
function iterate(obj){ var res=[]; for(var key in obj){ if(obj.hasOwnProperty(key)) res.push(key+': '+obj[key]); } return res; }