對象的建立有兩種方式,一種是直接用大括號直接建立,還有一種是用Object.create方法。函數
「var person1 = { name: "Nicholas", sayName: function() { console.log(this.name); } };」
var person2 = Object.create(person1, { name: { configurable: true, enumerable: true, value: "Greg", writable: true } });
實際應用過程當中,第二種方式比較少見。this
####1.Function方式 若是有以下函數,建立對象的實例一般用以下方式:prototype
function Person(name) { this.name = name; this.sayName = function() { console.log(this.name); }; } var p = new Person("aaa");
構造函數在哪裏?是什麼樣子的?其實這個時候,JS引擎隱式的構建了以一個構造函數,Person.prototype.constructor, 在new這個對象的時候,調用了這個構造函數,p.constructor == Person.prototype.constructor。 ####2. Prototype方式 用第一種方式存在一個問題,即每一個對象都會擁有name和sayName兩個屬性。而sayName做爲操做數據的方法,其實沒有必要每一個對象都有一份拷貝。爲了節省內存和更好的區分對象的數據和方法,一般會把方法放到prototype裏。形式以下:code
function Person(name) { this.name = name; } Person.prototype.sayName = function(){ console.log(this.name); }
這兩種方式生成的對象的行爲和方法是同樣的,可是第二種方式的sayName不在是對象實例的OwnProperty,檢測結果將返回false:對象
var p1 = new Person("a") p1.hasOwnProperty('sayName') //false
那麼既然第二種方式更好,在定義多個方法的時候,有人會進一步簡化成:內存
function Person(name) { this.name = name; } Person.prototype= { sayName:function(){ console.log(this.name); }, sayHi:function(){ console.log('Hi'+this.name); } }
這樣看似很好,可是檢測下構造函數後,發現有問題:it
Person.prototype.constructor //function Object() { [native code] }
這是由於Person.prototype={}的過程當中,Object的constructor覆蓋了Person.prototype.constructor。解決方法是把constructor從新覆蓋回來。io
Person.prototype= { constructor:Person, sayName:function(){ console.log(this.name); }, sayHi:function(){ console.log('Hi'+this.name); } }