DOM 객체에 속성을 설정할 때 매개 변수 재 할당을 방지하는 방법


97

주요 목적은 DOM 개체에 속성을 설정하는 방법이 있습니다.

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

ESLint에서 no-param-reassign오류를 발생 시키는 AirBnB의 코드 스타일을 사용 합니다.

함수 매개 변수 'el'에 대한 오류 할당 no-param-reassign

AirBnB의 코드 스타일을 준수하면서 인수로 전달 된 DOM 객체를 어떻게 조작 할 수 있습니까?

누군가 /* eslint react/prop-types: 0 */다른 문제를 언급하는 것을 제안 했지만 내가 착각하지 않는다면 이것은 반응에는 잘 적용되지만 네이티브 DOM 조작에는 적용되지 않습니다.

또한 코드 스타일을 변경하는 것이 답이라고 생각하지 않습니다. 표준 스타일 사용의 이점 중 하나는 프로젝트 전반에 걸쳐 일관된 코드를 유지하고 규칙을 변경하는 것이 AirBnB와 같은 주요 코드 스타일을 오용하는 것처럼 느껴진다는 것입니다.

기록을 위해 GitHub의 AirBnB에 질문 # 766 에서 이러한 경우 대처할 방법이 무엇이라고 생각하는지 물었습니다 .


아니. 첫째, 이는이 규칙이 의미가있는 다른 모든 발생에 대해이 기능을 비활성화하는 것을 의미합니다. 둘째로 나는 당신이 스타일 가이드를 따르거나 따르지 않는다고 믿습니다. 적어도 모든 종류의 프로젝트에서 많은 개발자가 따르는 스타일 가이드라면.
Lukas는

2
그러나 당신은 방지하려는 일을하고 있기 때문에 스타일 가이드를 따르지 않는 방법을 묻는 것입니다. 어쨌든, 그냥 그 기능에 대해 비활성화하십시오
Mathletics


@Mathletics 아니요 규칙이 타당하다고 생각하지만이 특정 경우에는 작동하지 않습니다. 규칙에 따라 이렇게하는 방법이 있는지 궁금합니다.
Lukas는

어떻게 말하든 원하는 작업이 규칙과 충돌합니다. 즉, XY 문제처럼 보입니다. 이와 같은 DOM 노드에 직접 속성을 연결하지 않습니다.
Mathletics

답변:


102

@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
즉, res.session즉시 수정하고 싶을 때가있는 nodejs 익스프레스 프로젝트의 경우 정말 의미가 있습니다
David

문제가 질문에 명시된대로 함수 매개 변수의 속성을 설정하는 데만있는 경우 아래 Gyandeep의 답변이 훨씬 좋습니다.
Prashanth Chandra

88

이 기사에서 설명하는 것처럼 규칙은 arguments객체의 변형을 방지하기위한 입니다. 매개 변수에 할당 한 다음 arguments개체 를 통해 일부 매개 변수에 액세스하려고 하면 예기치 않은 결과가 발생할 수 있습니다.

규칙을 그대로 유지하고 다른 변수를 사용하여 DOM 요소에 대한 참조를 가져온 다음 수정하여 AirBnB 스타일을 유지할 수 있습니다.

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

(DOM 노드 포함) JS 개체에서, 그래서 여기에 참조로 전달 eltheElement같은 DOM 노드에 대한 참조가 있지만, 개량이 theElement변이없는 arguments사람 개체 arguments[0]남아 그 DOM 요소 단지 참조.

이 접근 방식은 규칙 에 대한 문서에 암시되어 있습니다 .

이 규칙에 대한 올바른 코드의 예 :

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

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

개인적으로 나는 "no-param-reassign": ["error", { "props": false }]언급 된 몇 가지 다른 답변에 접근 방식을 사용합니다 . 매개 변수의 속성을 수정해도 해당 매개 변수가 참조하는 내용이 변경되지 않으며이 규칙이 피하려는 종류의 문제가 발생하지 않아야합니다.


6
이것은 행동을 회피하는 방법이 아니라 받아 들여진 대답이어야합니다. 이 답변 이후 공식 ESLint 문서에 명시된대로 Patric Bacon은 특정 시나리오에서 발생할 수있는 명확한 문제를 지적합니다. spin.atomicobject.com/2011/04/10/…
Remi

1
이 답변은 공식 문서를 가리키고 잘 설명되어 있으므로 허용되는 답변이어야합니다. 다른 대답의 대부분은 화재 경보기를 끄는 것과 같습니다!
Hamid Parchami

"지역 변수 'theElement'가 중복됩니다."라는 메시지가 표시 될 수 있습니다.
Phạm Tuấn Anh

이러한 새로운 참조에 어떤 종류의 명명 체계를 사용 하시겠습니까? 나는 여기에 'My'를 두는 것을 절대적으로 싫어하지만 새로운 참조를 만들 때 이미 적절하게 이름이 지정된 매개 변수의 이름을 바꾸는 것은 정말 어렵고 직관적이지 않습니다.
GhostBytes

방금 확인하고 arguments[0]변이되었습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? ... theElement.expando = { p: 2 }; return arguments[0].expando; ....
mrmowji

20

.eslintrc파일 내에서이 규칙을 재정의하고 다음 과 같은 매개 변수 속성에 대해 비활성화 할 수 있습니다.

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

이 방법으로 규칙은 여전히 ​​활성 상태이지만 속성에 대해 경고하지 않습니다. 추가 정보 : http://eslint.org/docs/rules/no-param-reassign


3
이 답변이 수락 된 답변에 완전히 포함되어 있지 않습니까?
Dan Dascalescu

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
});

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

다른 모든 것은 추악한 해킹입니다.


2

이 규칙을 선택적으로 비활성화하려는 사람들은 매개 변수 재 할당을 무시해야하는 객체 이름의 "화이트리스트"를 허용하는 규칙 에 대해 제안 된 새로운 옵션 에 관심이있을 수 있습니다 no-param-reassign.


위 내용은 담당자 점수가 부족하여 댓글이 아닌 답변으로 게시되었습니다.
RH Becker




-1

당신이 사용할 수있는:

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

1
이것은 사본 만 수정하지 않습니까 (어떻게 가치가 있음)?
2,540,625

1
이것은 새로운 객체를 생성하지 않고 원래 객체를 수정해야하는 동안 새 객체를 생성하여 매개 변수 재 할당을 피하는 것을 의미하기 때문에 실제로 해결책이 아닙니다.
루카스

나는 params를 수정하지 않는 것을 선호하지만, 이렇게하면 linter가 오류를 일으키지 않을 경우 Object.defineProperty ()를 사용할 수도 있습니다.
올리버

이것은 전혀 작동하지 않습니다. 변수의 복사본을 만들고 속성을 새 개체로 복사하고 속성을 수정 한 다음 반환하지 않으므로 아무 일도 일어나지 않습니다. 반환 했더라도 전달 된 것과 같은 DOM 요소가 아닌 객체를 반환합니다. 그 위에는 Object.assign객체에서 대상 객체로 복사하는 것입니다. 이와 같은 DOM 요소에서 복사하려고하면 빈 객체가 생성됩니다.
쓸모없는 코드

Plus Object.assign는 순환 참조 (예 : 소켓 연결)를 사용하여 Object의 속성을 다시 지정하려는 경우 적절하게 작동하지 않습니다. Object.assign기본적으로 얕은 복사본이며 성능 저하로 인해 깊은 복제는 매우 눈살을 찌푸립니다.
ILikeTacos

-1

객체 배열 내의 값을 변경하려면 다음을 사용할 수 있습니다.

array.forEach(a => ({ ...a, expando: {} }))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.