DOMオブジェクトのプロパティを設定するときにno-param-reassignを回避する方法


94

DOMオブジェクトにプロパティを設定することを主な目的とするメソッドがあります

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

ESLintにno-param-reassignエラーをスローさせるAirBnBのコードスタイルを使用します。

エラー関数パラメーター 'el'への割り当てno-param-reassign

AirBnBのコードスタイルに準拠しながら、引数として渡されたDOMオブジェクトを操作するにはどうすればよいですか?

誰かが別の問題/* eslint react/prop-types: 0 */を参照することを使用することを提案しましたが、私が間違っていない場合、これは反応には当てはまりますが、ネイティブDOM操作には当てはまりません。

また、コードスタイルを変更するのは正解ではないと思います。標準スタイルを使用する利点の1つは、プロジェクト間で一貫したコードがあり、ルールを自由に変更できることは、AirBnBのような主要なコードスタイルの誤用のように感じることだと思います。

参考までに、私はGitHubでAirBnBに質問しました。彼らは、問題#766でこれらのケース行く方法を彼らがどう思うかを尋ねました。


いや。まず、これは、このルールが意味をなす他のすべての発生に対してこれを無効にすることを意味します。第二に、私はあなたがスタイルガイドに従うか、従わないと信じています。少なくとも、あらゆる種類のプロジェクトにわたって多くの開発者が従うスタイルガイドである場合。
Lukas 2016

2
しかし、あなたはスタイルガイドに従わないように求めてます。いずれの場合でも、その機能に対して無効にしてください
Mathletics '25


@Mathleticsいいえルールは意味がありませんが、この特定のケースでは機能しません。ルールに沿ってこれを行う方法があるかどうか私は思っていました。
Lukas 2016

どのように表現しても、必要な操作はルールと矛盾します。とはいえ、XY問題のようです。そのようなDOMノードに直接プロパティをアタッチすることはしません。
Mathletics

回答:


100

@Mathleticsが示唆するように、これをファイルに追加することでルールを完全に無効にすることができ.eslintrc.jsonます:

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

または、特にparamプロパティのルールを無効にすることもできます

"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
ありがとうございました。ほとんどの人はリンターを変更するのが最善の方法だと思っているようです。これを単一の回線に適用することは、今の私にとって最良のトレードオフのようです。
Lukas

2
本当にnodejsのために、すなわち意味をなさないということは時々変更する場合がありますプロジェクト、表明res.sessionすぐ
デヴィッド・

問題が質問で述べられているように関数パラメーターのプロパティを設定することだけにある場合、以下のGyandeepの答えははるかに優れています。
Prashanthチャンドラ2017

85

この記事では説明して、このルールは、変異を避けることを意図しているargumentsオブジェクトを。パラメータに割り当ててから、argumentsオブジェクトを介して一部のパラメータにアクセスしようとすると、予期しない結果が生じる可能性があります。

別の変数を使用してDOM要素への参照を取得し、それを変更することで、ルールをそのまま維持し、AirBnBスタイルを維持できます。

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

JSでは、オブジェクト(DOMノードを含む)は参照によって渡されるため、ここeltheElementは同じ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
この回答は公式のドキュメントを指し示し、十分に説明されているため、受け入れられた回答である必要があります。他の答えのほとんどは、火災警報器をオフにするようなものです!
Hamid Parchami

「ローカル変数「theElement」は冗長です」が表示される場合があります。
ファム・トゥアン・アイン

これらの新しい参照にはどのような命名規則を使用しますか?ここで「My」を前に置くことは絶対に嫌いですが、新しい参照を作成するときに、すでに適切な名前のパラメーターの名前を変更することは非常に難しく、直観に反しています。
GhostBytes

私はちょうどチェックして、arguments[0]変異しました。何が悪いのですか?... theElement.expando = { p: 2 }; return arguments[0].expando; ...
mrmowji

20

このルールを.eslintrcファイル内でオーバーライドして、このようなparamプロパティに対して無効にすることができます

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

このように、ルールはまだアクティブですが、プロパティについて警告しません。詳細:http : //eslint.org/docs/rules/no-param-reassign


3
この答えは受け入れられたものに完全に含まれていませんか?
Dan Dascalescu 2018年

1
@DanDascalescu受け入れられた回答の下にこのコメントを指すコメントがあるので、ある時点でより包括的になるように編集されたのでしょうか?
bigsee

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パラメータ再割り当てを無視すべきに関しては、オブジェクト名の「ホワイトリスト」を可能とするルール。


上記は、担当者が不足しているため、コメントではなく回答として投稿されました。
RHベッカー




-1

以下を使用できます。

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

1
これはコピーを変更するだけではありませんか(それはどのように価値がありますか)?
2540625 16

1
これは実際にはソリューションではありません。これは、新しいオブジェクトを作成せずに元のオブジェクトを変更する必要があるのに、新しいオブジェクトを作成しパラメーターの再割り当てを回避することを意味するためです。
Lukas

私はparamsを変更しないことを好みますが、この方法でリンターがエラーをスローしないようにする場合、Object.defineProperty()を使用することもできます。
Oliver

これはまったく機能しません。変数のコピーを作成し、そのプロパティから新しいオブジェクトにプロパティをコピーし、プロパティを変更してから返さないため、何も起こりません。それを返したとしても、渡されたもののようなDOM要素ではなく、オブジェクトを返します。その上Object.assign、オブジェクトからターゲットオブジェクトにコピーするためのものです。そのようなDOM要素からコピーしようとすると、空のオブジェクトになります。
役に立たないコード

Object.assign循環参照(たとえば、ソケット接続)を使用してObjectのプロパティを再アサートしようとすると、Plus は適切に機能しません。Object.assignデフォルトでは浅いコピーであり、パフォーマンスに影響があるため、ディープクローニングは非常に困難です。
ILikeTacos 2018年

-1

オブジェクト配列内の値を変更したい場合は、

array.forEach(a => ({ ...a, expando: {} }))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.