2015-12-29 61 views
1

我最近看到了JavaScript代碼,其中getter和setter方法在構造函數方法的原型對象上定義。定義對象或object.prototype的屬性?

例如:

Person.prototype.getFirstName = function() { 
    return this.firstName; 
} 

這是正確的嗎?

我的意思是: 'this'指向調用該方法的對象的描述符。

當我打電話,會發生什麼......

console.log(Person.getFirstName()); 

...未做一個對象之前?

此外:

是否有何時的屬性附加到構造函數法和時附加到原型的對象一般規則?

如果您不一定需要創建對象,那麼從我的角度來看,它是附加在原型上的。因爲該方法不使用必須單獨設置對象的對象的值。

回答

3

當我打電話,會發生什麼......

console.log(Person.getFirstName()); 

...沒有事先製作的對象?

您收到錯誤消息Person沒有getFirstName屬性。

是否有附加屬性到構造函數方法和何時附加到原型對象的一般規則?

是:

如果你想方法可用上通過構造函數創建的對象(例如,obj,var obj = new Person()),將該方法放在構造函數的prototype對象(共享)上,或者通過分配給this(不共享)的屬性將該方法分配給構造函數中的對象。

如果你想方法可用在構造函數本身,這樣一些內置的JavaScript方法(如Date.parseObject.create),其分配給屬性的構造函數:

Person.doSomething = function() { 
    // ... 
}; 

這些方法不是特定於由構造函數創建的對象(其中的this是對構造函數本身的引用,除非您採取某些措施使其不同)。

如果你從一個基於類的語言來,一個很寬鬆的比喻是,性質(包括方法)分配給prototype對象的構造函數或this在構造函數中是實例屬性,而你分配給構造函數本身的是靜態屬性。這是一個非常寬鬆的比喻,但有時很有幫助。

這裏的老ES5和早期語法一個完整的例子:

function Person(name) { 
    this.getName = function() { 
     return name; 
    }; 
} 
Person.prototype.sayHello = function() { 
    console.log("Hello, my name is " + this.getName()); 
}; 
Person.copy = function(other) { 
    return new Person(other.getName()); 
}; 

// Usage example 
var joe = new Person("Joe"); 
joe.sayHello(); 
console.log("joe's name is " + joe.getName()); 
var joeagain = Person.copy(joe); 
joeagain.sayHello(); 

在上面:

  • getName可以用實例通過new Person創建。它是爲每個對象單獨創建的,不與其他實例共享。它讓我們獲取該人員的姓名,在本例中爲只讀。

  • sayHello可以用實例通過new Person創建,因爲他們從他們的原型,這是從Person.prototype財產分配給他們的new Person繼承它。它在實例之間共享。

  • copy在實例上不可用(joe.copy()將是錯誤),它是Person本身的屬性。在這種情況下,我們用它來複制實例,但它可能適用於任何事情。

+0

太棒了。你幫了我很多。謝謝。 :) –

0

原型獲得通過new關鍵字

因此,代碼實例它繼承

var Person = function(){} 
Person.prototype.getFirstName = function() { 
    return this.firstName; 
} 

Person.prototype.firstName = "test"; 

console.log(Person.getFirstName()); // Throw Uncaught TypeError 

正確的方法是:

var Person2 = new Person() 
Person2.getFirstName() // "test" 

爲了測試這個對象:

所以PersonPrototype設爲this對象PERSON2(繼承)的

這類似於Class如Java或C#語言。

0

就個人而言,我不喜歡在原型中添加getter,如果您只想訪問實例值。您可以通過實例已經訪問這些值:

function Person(name) { 
    this.firstname = name; 
} 
Person.prototype.getFirstname = function() { 
    return this.firstname; 
} 
var p = new Person('o-o'); 
console.log(p.firstname); //o-o 
console.log(p.getFirstname()); //o-o 

你可以添加一個getter原型傳遞不同的環境:

var firstname = Person.prototype.getFirstname.call({firstname: 'other'}); 
console.log(firstname); // other 

如果是的話它會是有意義的一個getter增加原型增加了一些計算:

Person.prototype.getFirstname = function() { 
    return new Date().toISOString + ': ' + this.firstname; 
}; 

如果策略適合你的需要,你可以以不同的編排代碼:

var common = { 
    getValue = function(propName) { 
    return new Date().toISOString() + ': ' + this[propName]; 
    } 
}; 

function Person(name) { 
    this.firstname = name; 
} 

$.extend(Person.prototype, common); //jQuery extend 
var p = new Person('o-o'); 
console.log(p.firstname); //o-o 
console.log(p.getValue('firstname')); //today: o-o 

擴展您的原型還帶有一個多功能common:開發過程中添加日誌記錄信息並丟棄那些生產多餘的日誌記錄信息。