javascript - ES6 कक्षाओं में स्थिर स्थिरांक घोषित करना?





class constants ecmascript-6 (8)


आप ईएस 6 कक्षाओं की एक अजीब विशेषता का उपयोग कर कक्षा में स्थिर स्थिरांक को परिभाषित करने का एक तरीका बना सकते हैं। चूंकि सांख्यिकी उनके उप-वर्गों द्वारा विरासत में प्राप्त होती है, इसलिए आप निम्न कार्य कर सकते हैं:

const withConsts = (map, BaseClass = Object) => {
  class ConstClass extends BaseClass { }
  Object.keys(map).forEach(key => {
    Object.defineProperty(ConstClass, key, {
      value: map[key],
      writable : false,
      enumerable : true,
      configurable : false
    });
  });
  return ConstClass;
};

class MyClass extends withConsts({ MY_CONST: 'this is defined' }) {
  foo() {
    console.log(MyClass.MY_CONST);
  }
}

मैं class में स्थिरांक को कार्यान्वित करना चाहता हूं, क्योंकि वह कोड में उन्हें ढूंढने के लिए समझ में आता है।

अब तक, मैं स्थिर तरीकों के साथ निम्नलिखित कार्यवाही लागू कर रहा हूं:

class MyClass {
    static constant1() { return 33; }
    static constant2() { return 2; }
    // ...
}

मुझे पता है प्रोटोटाइप के साथ झुकाव की संभावना है, लेकिन कई इसके खिलाफ सिफारिश करते हैं।

ES6 कक्षाओं में स्थिरांक लागू करने का कोई बेहतर तरीका है?




class Whatever {
    static get MyConst() { return 10; }
}

let a = Whatever.MyConst;

लगता है मेरे लिए काम करता है।




यहां एक और तरीका है जो आप कर सकते हैं

/*
one more way of declaring constants in a class,
Note - the constants have to be declared after the class is defined
*/
class Auto{
   //other methods
}
Auto.CONSTANT1 = "const1";
Auto.CONSTANT2 = "const2";

console.log(Auto.CONSTANT1)
console.log(Auto.CONSTANT2);

नोट - ऑर्डर महत्वपूर्ण है, आप ऊपर स्थिरांक नहीं रख सकते हैं

उपयोग console.log (Auto.CONSTANT1);




मैं babel का उपयोग कर रहा हूं और निम्नलिखित वाक्यविन्यास मेरे लिए काम कर रहा है:

class MyClass {
    static constant1 = 33;
    static constant2 = {
       case1: 1,
       case2: 2,
    };
    // ...
}

MyClass.constant1 === 33
MyClass.constant2.case1 === 1

कृपया ध्यान दें कि आपको प्रीसेट "stage-0"
इसे स्थापित करने के लिए:

npm install --save-dev babel-preset-stage-0

// in .babelrc
{
    "presets": ["stage-0"]
}

अद्यतन करें:

वर्तमान में stage-2 उपयोग करें




Object.freeze का उपयोग कक्षा (ईएस 6) / कन्स्ट्रक्टर फ़ंक्शन (ईएस 5) ऑब्जेक्ट पर अपरिवर्तनीय बनाने के लिए भी संभव है:

class MyConstants {}
MyConstants.staticValue = 3;
MyConstants.staticMethod = function() {
  return 4;
}
Object.freeze(MyConstants);
// after the freeze, any attempts of altering the MyConstants class will have no result
// (either trying to alter, add or delete a property)
MyConstants.staticValue === 3; // true
MyConstants.staticValue = 55; // will have no effect
MyConstants.staticValue === 3; // true

MyConstants.otherStaticValue = "other" // will have no effect
MyConstants.otherStaticValue === undefined // true

delete MyConstants.staticMethod // false
typeof(MyConstants.staticMethod) === "function" // true

कक्षा को बदलने की कोशिश करने से आपको मुलायम असफल हो जाएगा (किसी भी त्रुटि को फेंक नहीं देगा, इसका कोई असर नहीं होगा)।




यहां कुछ चीज़ें दी गई हैं जो आप कर सकते हैं:

मॉड्यूल से एक const निर्यात करें। आपके उपयोग के मामले के आधार पर, आप बस:

export const constant1 = 33;

और जहां आवश्यक हो मॉड्यूल से आयात करें। या, अपने स्थैतिक विधि विचार पर निर्माण, आप static प्राप्तकर्ता घोषित कर सकते हैं:

const constant1 = 33,
      constant2 = 2;
class Example {

  static get constant1() {
    return constant1;
  }

  static get constant2() {
    return constant2;
  }
}

इस तरह, आपको कोष्ठक की आवश्यकता नहीं होगी:

const one = Example.constant1;

बेबेल आरईपीएल उदाहरण

फिर, जैसा कि आप कहते हैं, चूंकि एक class केवल एक समारोह के लिए सिंटैक्टिक चीनी है, इसलिए आप एक गैर-लेखन योग्य संपत्ति को जोड़ सकते हैं:

class Example {
}
Object.defineProperty(Example, 'constant1', {
    value: 33,
    writable : false,
    enumerable : true,
    configurable : false
});
Example.constant1; // 33
Example.constant1 = 15; // TypeError

यह अच्छा हो सकता है अगर हम कुछ ऐसा कर सकें:

class Example {
    static const constant1 = 33;
}

लेकिन दुर्भाग्यवश यह वर्ग संपत्ति वाक्यविन्यास केवल ईएस 7 प्रस्ताव में है, और फिर भी यह संपत्ति को const करने की अनुमति नहीं देगा।




तरह, मुझे लगता है कि आप Object.freeze() । अपरिवर्तनीय statics के साथ एक वर्ग का एक उदाहरण यहां दिया गया है:

class User {
  constructor(username, age) {
    if (age < User.minimumAge) {
      throw new Error('You are too young to be here!');
    }
    this.username = username;
    this.age = age;
    this.state = 'active';
  }
}

User.minimumAge = 16;
User.validStates = ['active', 'inactive', 'archived'];

deepFreeze(User);

function deepFreeze(value) {
  if (typeof value === 'object' && value !== null) {
    Object.freeze(value);
    Object.getOwnPropertyNames(value).forEach(property => {
      deepFreeze(value[property]);
    });
  }
  return value;
}



IE6 समर्थन के साथ वेनिला जावास्क्रिप्ट में एक तत्व की कक्षा बदलें

पुराने ब्राउज़र के साथ संगतता रखने के लिए आप नोड attributes का उपयोग करने का प्रयास कर सकते हैं I6:

function getClassNode(element) {
  for (var i = element.attributes.length; i--;)
    if (element.attributes[i].nodeName === 'class')
      return element.attributes[i];
}

function removeClass(classNode, className) {
  var index, classList = classNode.value.split(' ');
  if ((index = classList.indexOf(className)) > -1) {
    classList.splice(index, 1);
    classNode.value = classList.join(' ');
  }
}

function hasClass(classNode, className) {
  return classNode.value.indexOf(className) > -1;
}

function addClass(classNode, className) {
  if (!hasClass(classNode, className))
    classNode.value += ' ' + className;
}

document.getElementById('message').addEventListener('click', function() {
  var classNode = getClassNode(this);
  var className = hasClass(classNode, 'red') && 'blue' || 'red';

  removeClass(classNode, 'red');
  removeClass(classNode, 'blue');

  addClass(classNode, className);
})
.red {
  color: red;
}
.red:before {
  content: 'I am red! ';
}
.red:after {
  content: ' again';
}
.blue {
  color: blue;
}
.blue:before {
  content: 'I am blue! '
}
<span id="message" class="">Click me</span>







javascript class constants ecmascript-6