DOM ऑब्जेक्ट पर प्रॉपर्टी सेट करते समय no-param-reassign से कैसे बचें


94

मेरे पास एक विधि है जिसका मुख्य उद्देश्य एक डोम ऑब्जेक्ट पर एक संपत्ति निर्धारित करना है

function (el) {
  el.expando = {};
}

मैं AirBnB की कोड शैली का उपयोग करता हूं जो ESLint को एक no-param-reassignत्रुटि देता है:

पैरामीटर 'एल' नो-परम-रिअसाइन को कार्य करने के लिए त्रुटि असाइनमेंट

मैं AirBnB की कोड शैली के अनुरूप एक DOM ऑब्जेक्ट को तर्क के रूप में कैसे हेरफेर कर सकता हूं?

किसी ने किसी अन्य मुद्दे का /* eslint react/prop-types: 0 */उल्लेख करने का उपयोग करने का सुझाव दिया, लेकिन अगर मैं गलत नहीं हूं तो यह प्रतिक्रिया के लिए अच्छी तरह से लागू होता है, लेकिन मूल डोम हेरफेर के लिए नहीं।

इसके अलावा, मुझे नहीं लगता कि कोड शैली बदलना एक उत्तर है। मेरा मानना ​​है कि मानक शैली का उपयोग करने के लाभों में से एक है परियोजनाओं में लगातार कोड होना और नियमों को बदलना एयरबर्न्स जैसी प्रमुख कोड शैली का दुरुपयोग महसूस होगा।

रिकॉर्ड के लिए, मैंने GitHub पर AirBnB से पूछा, उन्हें क्या लगता है कि # 766 इश्यू में इन मामलों में जाने का तरीका क्या है ।


नाह। सबसे पहले, इसका मतलब यह होगा कि अन्य सभी घटनाओं के लिए यह अक्षम करना जहां यह नियम समझ में आता है। दूसरी बात, मेरा मानना ​​है कि आप या तो स्टाइल गाइड का पालन करते हैं या नहीं। कम से कम अगर यह एक स्टाइल गाइड है तो कई डेवलपर्स द्वारा सभी प्रकार की परियोजनाओं के बाद।
लुकास

2
लेकिन आप पूछ रहे हैं कि स्टाइलगाइड को कैसे मानें, क्योंकि आप जिस चीज को रोकने की कोशिश कर रहे हैं, वह कर रहे हैं। किसी भी मामले में, बस इसे उस फ़ंक्शन के लिए अक्षम करें
मैथलेटिक्स


@ मैथलेटिक्स नहीं मुझे नियम कामुक लगता है, लेकिन यह सिर्फ इस विशिष्ट मामले के लिए काम नहीं करता है। मैं सोच रहा था कि क्या इस नियम के साथ खेलने का कोई तरीका है।
लुकास

कोई फर्क नहीं पड़ता कि आप इसे कैसे कहते हैं, ऑपरेशन जिसे आप नियम के साथ संघर्ष चाहते हैं। उस ने कहा, यह एक XY समस्या की तरह लगता है; मैं उस तरह से सीधे डीओडी नोड्स में गुण संलग्न नहीं करूंगा।
मैथलेटिक्स 20

जवाबों:


100

जैसा कि @ मैथलेटिक्स से पता चलता है, आप इसे अपनी फ़ाइल में जोड़कर नियम को पूरी तरह से अक्षम कर सकते हैं.eslintrc.json :

"rules": {
  "no-param-reassign": 0
}

या आप विशेष रूप से परम गुणों के लिए नियम को अक्षम कर सकते हैं

"rules": {
  "no-param-reassign": [2, { "props": false }]
}

वैकल्पिक रूप से, आप उस फ़ंक्शन के लिए नियम को अक्षम कर सकते हैं

/* eslint-disable no-param-reassign */
function (el) {
  el.expando = {};
}
/* eslint-enable no-param-reassign */

या उस लाइन के लिए ही

function (el) {
  el.expando = {}; // eslint-disable-line no-param-reassign
}

आप विशेष रूप से AirBnB के स्टाइल गाइड को समायोजित करने के लिए ESLint नियमों को अक्षम करने पर इस ब्लॉग पोस्ट को भी देख सकते हैं।


1
धन्यवाद। ऐसा लगता है कि ज्यादातर लोग लिंटर को सबसे बेहतर तरीके से संशोधित करते हैं। इसे एक ही लाइन के लिए लागू करना मेरे लिए सबसे अच्छा व्यापार बंद लगता है।
लुकास

2
यह वास्तव में समझ में आता है कि नोड्ज एक्सप्रेस परियोजनाओं के लिए, जहां कभी-कभी आप res.sessionसीधे दूर संशोधित करना चाहते हैं
डेविड

यदि समस्या केवल फ़ंक्शन मापदंडों के गुणों को स्थापित करने के साथ है जैसा कि प्रश्न में कहा गया है, तो नीचे Gyandeep का उत्तर बहुत बेहतर है।
प्रशान्त चन्द्र

85

जैसा कि इस लेख में बताया गया है , यह नियम argumentsऑब्जेक्ट को म्यूट करने से बचने के लिए है । यदि आप किसी पैरामीटर को असाइन करते हैं और फिर argumentsऑब्जेक्ट के माध्यम से कुछ मापदंडों का उपयोग करने का प्रयास करते हैं , तो यह अप्रत्याशित परिणाम ला सकता है।

आप DOM तत्व का संदर्भ पाने के लिए किसी अन्य चर का उपयोग करके नियम को बरकरार रख सकते हैं और AirBnB शैली को बनाए रख सकते हैं और फिर संशोधित कर सकते हैं:

function (el) {
  var theElement = el;
  theElement.expando = {};
}

JS ऑब्जेक्ट्स (DOM नोड्स सहित) को संदर्भ के द्वारा पास किया जाता है, इसलिए यहाँ elऔर theElementउसी DOM नोड के संदर्भ हैं, लेकिन ऑब्जेक्ट को संशोधित theElementनहीं करता है argumentsक्योंकि arguments[0]यह केवल उस DOM तत्व का संदर्भ है।

इस दृष्टिकोण को नियम के लिए प्रलेखन में संकेत दिया गया है :

इस नियम के लिए सही कोड के उदाहरण:

/*eslint no-param-reassign: "error"*/

function foo(bar) {
    var baz = bar;
}

व्यक्तिगत रूप से, मैं सिर्फ "no-param-reassign": ["error", { "props": false }]दृष्टिकोण का उल्लेख किया अन्य जवाब के एक जोड़े का उपयोग करेगा । पैरामीटर की एक संपत्ति को संशोधित करना उस पैरामीटर को म्यूट नहीं करता है जो उस पैरामीटर को संदर्भित करता है और उस प्रकार की समस्याओं में नहीं चलना चाहिए जो इस नियम से बचने की कोशिश कर रहा है।


5
यह स्वीकृत उत्तर होना चाहिए, व्यवहार को दरकिनार करने का तरीका नहीं। इस उत्तर के बाद से, और पेट्रिक बेकन ने आधिकारिक ESLint प्रलेखन में कहा कि एक स्पष्ट समस्या है जो कुछ परिदृश्यों में इसके साथ हो सकती है: spin.atomicobject.com/2011/04/10/-
रेमी

1
यह उत्तर स्वीकृत उत्तर होना चाहिए क्योंकि यह आधिकारिक दस्तावेज की ओर इशारा करता है और अच्छी तरह से समझाया गया है। अधिकांश अन्य उत्तर फायर अलार्म को बंद करने जैसे हैं!
हामिद परचमी

आपको "स्थानीय चर 'theElement' अनावश्यक मिल सकता है।"
Ph19m Tuạn Anh

इन नए संदर्भों के लिए आप किस प्रकार की नामकरण योजना का उपयोग करेंगे? मैं यहां चीजों के सामने 'माई' लगाने से बिल्कुल नफरत करता हूं लेकिन नया संदर्भ बनाते समय पहले से ही नामांकित मापदंडों का नाम बदलना वास्तव में कठिन और यहां तक ​​कि सहज है।
घोस्टबाइट्स

मैंने अभी-अभी चेक किया arguments[0]था और म्यूट कर दिया गया था। मैं क्या गलत कर रहा हूं? ... theElement.expando = { p: 2 }; return arguments[0].expando; ...
म्रमोवजी

20

आप अपनी .eslintrcफ़ाइल के अंदर इस नियम को ओवरराइड कर सकते हैं और इसे इस तरह के परम गुणों के लिए अक्षम कर सकते हैं

{
    "rules": {
        "no-param-reassign": [2, { 
            "props": false
        }]
    },
    "extends": "eslint-config-airbnb"
}

इस तरह से नियम अभी भी सक्रिय है लेकिन यह गुणों के लिए चेतावनी नहीं देगा। अधिक जानकारी: http://eslint.org/docs/rules/no-param-reassign


3
क्या यह उत्तर पूरी तरह से स्वीकृत में शामिल नहीं है?
डैन डस्केल्सस्कु

1
@DanDascalescu इस एक की ओर इशारा करते हुए स्वीकार किए गए उत्तर के नीचे एक टिप्पणी है, इसलिए शायद इसे कुछ बिंदुओं पर संपादित किया गया है ताकि यह अधिक व्यापक हो सके?
बिगसी

11

no-param-reassignचेतावनी आम कार्यों के लिए समझ में आता है, लेकिन एक क्लासिक के लिएArray.forEach एक सरणी जो आप इसे उत्परिवर्तित करने का इरादा अधिक पाश उचित नहीं है।

हालाँकि, इसे प्राप्त करने के लिए, आप Array.mapएक नई वस्तु के साथ भी उपयोग कर सकते हैं (यदि आप मेरे जैसे हैं, तो टिप्पणियों के बारे में चेतावनियाँ देना पसंद नहीं करते हैं:

someArray = someArray.map((_item) => {
    let item = Object.assign({}, _item); // decouple instance
    item.foo = "bar"; // assign a property
    return item; // replace original with new instance
});

3
function (el) {
  el.setAttribute('expando', {});
}

बाकी सब सिर्फ बदसूरत हैक्स है।


2

इस नियम को चुनिंदा रूप से निष्क्रिय करने की इच्छा रखने वालों को उस नियम के लिए प्रस्तावित नए विकल्प में रुचि हो सकती no-param-reassignहै जो ऑब्जेक्ट नामों की "सफेद सूची" की अनुमति देगा जिसके संबंध में पैरामीटर पुन: असाइनमेंट को अनदेखा किया जाना चाहिए।


प्रतिनिधि के अभाव के कारण, टिप्पणी के बजाय उत्तर को पोस्ट किया गया था।
आरएच बेकर



0

डेटा अपडेट करने के लिए आप विधियों का उपयोग कर सकते हैं। उदाहरण के लिए। "res.status (404)" के बजाय "res.statusCode = 404" मैंने समाधान ढूंढ लिया। https://github.com/eslint/eslint/issues/6505#issuecomment-282325903

/*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsFor": ["$scope"] }]*/

app.controller('MyCtrl', function($scope) {
  $scope.something = true;
});

-1

आप उपयोग कर सकते हैं:

(param) => {
  const data = Object.assign({}, param);
  data.element = 'some value';
}

1
क्या यह केवल प्रति को संशोधित नहीं करता है (यह कैसे मूल्यवान है)?
२५४०६२५

1
यह वास्तव में एक समाधान नहीं है क्योंकि इसका मतलब है कि एक नई वस्तु का निर्माण करके परम पुनर्मूल्यांकन से बचना, जबकि मुझे स्पष्ट रूप से एक नई वस्तु बनाने की आवश्यकता नहीं है लेकिन मूल को संशोधित करना है।
लुकास

मैं पैरामेट्स को संशोधित नहीं करना पसंद करता हूं, लेकिन अगर आप इस तरह से करते हैं तो आप Object.defineProperty () का भी उपयोग कर सकते हैं, ताकि लिंटर आपको कोई त्रुटि न दे।
ओलिवर

यह बिल्कुल काम नहीं करेगा। आप चर की एक प्रति बना रहे हैं, एक नई वस्तु पर इसके गुणों को कॉपी कर रहे हैं, एक संपत्ति को संशोधित कर रहे हैं और फिर इसे वापस नहीं कर रहे हैं, इसलिए कुछ भी नहीं होता है। यहां तक ​​कि अगर आपने इसे वापस कर दिया है, तो आप एक वस्तु लौटा रहे हैं, न कि एक डोम तत्व की तरह जो इसमें पारित हो गया था। उसके शीर्ष पर, Object.assignएक वस्तु से लक्ष्य वस्तु की नकल करने के लिए है। किसी DOM ऑब्जेक्ट से कॉपी करने की कोशिश करना एक खाली वस्तु के रूप में परिणाम देता है।
बेकार कोड

Object.assignयदि आप किसी ऑब्जेक्ट पर परिपत्र संदर्भ (उदाहरण के लिए सॉकेट कनेक्शन) के साथ पुन: सहायता करने का प्रयास कर रहे हैं तो प्लस उचित रूप से काम नहीं करेगा। Object.assignडिफ़ॉल्ट रूप से एक उथली प्रति है, और प्रदर्शन के हिट होने के कारण गहरी क्लोनिंग बहुत परिलक्षित होती है।
ILikeTacos

-1

यदि आप किसी ऑब्जेक्ट ऐरे के अंदर कोई मान बदलना चाहते हैं, तो आप उपयोग कर सकते हैं

array.forEach(a => ({ ...a, expando: {} }))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.