2015-12-29 13 views
18

पर सेट करना मेरे पास एक गेटर संपत्ति के साथ एक ईएस 6 कक्षा (बैबेलज़ के साथ ट्रांसकंपल) है। मैं समझता हूं कि ये गुण डिफ़ॉल्ट रूप से गणना योग्य नहीं हैं। हालांकि, मुझे समझ नहीं आता क्यों मुझे Object.definePropertyईएस 6 क्लास गेटटर को

// Declare class 
class Person { 
    constructor(myName) { 
    this.name = myName; 
    } 

    get greeting() { 
    return `Hello, I'm ${this.name}`; 
    } 
} 

// Make enumerable (doesn't work) 
Object.defineProperty(Person, 'greeting', {enumerable: true}); 

// Create an instance and get enumerable properties 
var person = new Person('Billy'); 
var enumerableProperties = Object.keys(person); 
// => ['name'] 

Plunker Example

+0

प्रोटोटाइप ऑब्जेक्ट पर इसे परिभाषित करें। 'Object.defineProperty (Person.prototype, ...)' – Louy

+0

@Louy आपके सुझाव के साथ एक ही प्लंकर - कोई परिवर्तन नहीं: http://plnkr.co/edit/QkQ1JbFEjAAOIFPCtPk7?p=preview – lightswitch05

उत्तर

26

ES6 शैली ही टिककर खेल का उपयोग कर, प्रोटोटाइप पर परिभाषित कर रहे हैं प्रत्येक व्यक्ति person पर नहीं संपत्ति गणनीय बनाने के लिए सक्षम नहीं हूँ है। गणनीय को greeting गुण सेट करने के लिए आप को बदलने की जरूरत:

// Make enumerable (doesn't work) 
Object.defineProperty(Person, 'greeting', {enumerable: true}); 

करने के लिए:

// Make enumerable 
Object.defineProperty(Person.prototype, 'greeting', {enumerable: true}); 

Object.keys केवल रिटर्न कि वस्तुओं खुद गणनीय गुण है, इसलिए प्रोटोटाइप पर गुण वापस नहीं कर रहे हैं। आपको greeting संपत्ति Object.keys(Object.getPrototypeOf(person)) में या for...in लूप में मिलेगी। Updated Plunker

अगर इसके बजाय, आप व्यक्ति के प्रत्येक व्यक्ति के उदाहरण चाहते हैं अपने आप ही के लिए greeting आप निर्माता में परिभाषित कर सकते हैं:

class Person { 
    constructor(myName) { 
    this.name = myName; 

    Object.defineProperty(this, 'greeting', { 
     enumerable: true, 
     get: function () { return `Hello, I'm ${this.name}`; } 
    }); 
    } 
} 

Updated Plunker

+1

यह काम करता है लेकिन वाह, सहज नहीं है या यहां तक ​​कि तार्किक – lightswitch05

+0

आपको 'ऑब्जेक्ट.getOwnPropertyDescriptor (Person.prototype,' ग्रीटिंग ') से लौटाई गई वर्णक का उपयोग करने की आवश्यकता होगी अन्यथा आप' ग्रीटिंग 'वर्णनकर्ता को विस्तारित करने के बजाय * ओवरराइडिंग * कर रहे हैं और आप' get' व्यवहार को खो देते हैं। –

+3

@ सेनविएरा नहीं आपको इसकी आवश्यकता नहीं है। 'defineProperty' का उपयोग मौजूदा गुणों को संशोधित/कॉन्फ़िगर करने के लिए भी किया जा सकता है। जब तक आप 'मान' या नया 'प्राप्त' निर्दिष्ट नहीं करते हैं, तब तक गणना करने योग्य सेटिंग पुराने 'प्राप्त' को काम करने से नहीं रोकती है। (मेरे जवाब में जुड़े पहले प्लंकर में नोटिस कि 'व्यक्ति [नाम]' सही ढंग से ग्रीटिंग लौटाता है)। – Paulpro

0

आप इस तरह काम कर सकता है:

class Person { 
    static createFields({ name }) { 
    return { 
     name, 
     get greeting() { 
     return `Hello, I'm ${this.name}`; 
     } 
    } 
    } 

    constructor(...args) { 
    const inst = this.constructor.createFields(...args) 
    const desc = Object.getOwnPropertyDescriptors(inst) 
    Object.defineProperties(this, desc) 
    return this 
    } 
} 

लाभ यह है कि सादे ऑब्जेक्ट पर गेटर्स डिफ़ॉल्ट रूप से गणनीय और कॉन्फ़िगर करने योग्य हैं, आपको सी नहीं करना है हर बार इन संशोधकों के बारे में हैं।

लेकिन ... यह थोड़े अजीब दिखता है) सुनिश्चित नहीं है कि इसका वास्तव में उपयोग किया जाना चाहिए या नहीं।

संबंधित मुद्दे