programing

Airbnb 스타일 가이드는 왜 함수 이름 추론에 의존하지 말라고 하는가?

goodjava 2023. 3. 26. 11:21

Airbnb 스타일 가이드는 왜 함수 이름 추론에 의존하지 말라고 하는가?

// bad
class Listing extends React.Component {
  render() {
    return <div>{this.props.hello}</div>;
  }
}

// bad (relying on function name inference is discouraged)
const Listing = ({ hello }) => (
  <div>{hello}</div>
);

// good
function Listing({ hello }) {
  return <div>{hello}</div>;
}

이것은 Airbnb 리액트 스타일 가이드에서 가져온 것입니다."함수 이름 추론에 의존하는 것이 권장되지 않는 이유"를 설명해 주시겠습니까?그냥 스타일 고민인가요?

또, 이것은, 어나니머스 함수라고 생각되는 어휘명을 암묵적으로 붙이는 것으로부터 발생할지도 모르는 예기치 않은 행동과도 관계가 있다고 생각합니다.

예를 들어 화살표 기능을 이해한 사람이 있다고 합시다.

(x) => x+2;

정규 함수와 동등한 값을 가지려면:

function(x) {
  return x+2;
}

다음 코드를 예상하는 것은 매우 쉽습니다.

let foo = (x) => x+2;

다음에 상당하는 것:

let foo = function(x) {
  return x+2;
}

함수는 익명으로 유지되며 재귀와 같은 작업을 수행하기 위해 자신을 참조할 수 없습니다.

그래서 만약 우리의 행복한 무지 속에서 이런 일이 일어난다면:

let foo = (x) => (x<2) ? foo(2) : "foo(1)? I should be a reference error";
console.log(foo(1));

이 함수는 익명이 아니기 때문에 정상적으로 실행됩니다.

let foo = function foo(x) {
  return (x<2) ? foo(2) : "foo(1)? I should be a reference error";
}  

이것은 Babel이 익명 함수에 암묵적으로 이름을 추가하는 다른 상황에서는 더욱 악화될 수 있습니다(그것은 애초에 암묵적인 함수 이름을 지원하는 것의 부작용이라고 생각합니다만, 그 점은 틀릴 수 있습니다).엣지 케이스를 올바르게 처리하여 예상대로 참조 오류를 발생시킵니다.

예를 들어 다음과 같습니다.

let foo = {
  bar: function() {}
} 

// Will surprisingly transpile to..

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


// But doing something like:

var foo = {
  bar: function(x) {
    return (x<2) ? bar(2) : 'Whats happening!?';
  }
}

console.log(foo.bar(1));

// Will correctly cause a ReferenceError: bar is not defined

빠른 DEMO에서 '컴파일된 보기'를 확인하여 Babel이 익명 함수의 동작을 유지하기 위해 실제로 어떻게 변환하는지 확인할 수 있습니다.


즉, 코드로부터 무엇을 기대할 수 있는지 정확하게 알고 있기 때문에, 자신이 하고 있는 일을 명확하게 하는 것은, 통상 좋은 생각입니다.함수의 암묵적 명칭을 사용하지 않는 것은 간결하고 간결하게 유지하면서도 이를 뒷받침하는 스타일적인 선택일 수 있다.

그리고 아마 들어올렸을거야근데 재밌는 부업.

편집 #2: Javascript 스타일 가이드에서 AirBnbs 이유를 찾았습니다.

표현식 이름을 붙이는 것을 잊지 마십시오.익명의 함수는 에러의 콜 스택에서 문제를 찾기 어렵게 할 수 있습니다(토론).

원래의 답변은 다음과 같습니다.

MDN은 다음 두 가지 경고를 포함하여 함수 이름 추론이 어떻게 기능하는지 자세히 설명합니다.

관찰.

인 것이 .<function>.name다음과 같이 합니다.

  1. 스크립트 인터프리터를 사용하는 경우

스크립트 인터프리터는 함수에 name이라는 자체 속성이 없는 경우에만 함수의 이름 속성을 설정합니다.

  1. js 도구를 사용하는 경우

Function.name 및 JavaScript Compressor(미니퍼) 또는 난독화자에 의해 실행되는 소스 코드 변환 사용 시 주의하십시오.

....

압축되지 않은 버전에서는 프로그램이 truthy-branch로 실행되고 로그 'foo'는 Foo의 인스턴스인 반면 압축된 버전에서는 다르게 동작하며 else-branch로 실행됩니다.따라서 위의 예시와 같이 Function.name에 의존하는 경우 빌드 파이프라인이 함수 이름을 변경하거나 함수가 특정 이름을 가지고 있다고 가정하지 않는지 확인하십시오.

함수 이름 추론이란 무엇입니까?

name즉 (구현 전) functions 의 빈 합니다.

function doSomething() {}

console.log(doSomething.name); // logs "doSomething"

new function(...) 또는 just function(...) 구문으로 작성된 함수의 이름 속성은 빈 문자열로 설정됩니다.다음 예제에서는 익명 함수가 생성되므로 이름은 빈 문자열을 반환합니다.

var f = function() {};
var object = {
  someMethod: function() {}
};

console.log(f.name == ''); // true
console.log(object.someMethod.name == ''); // also true

ES6 기능을 구현하는 브라우저는 통사적 위치에서 익명 함수의 이름을 추론할 수 있다.예를 들어 다음과 같습니다.

var f = function() {};
console.log(f.name); // "f"

의견.

개인적으로 변수에 할당된 (화살표) 함수를 선호하는 이유는 다음과 같습니다.

첫째, 나는 절대 그것을 사용하지 않는다.function.name

둘째, 명명된 함수의 어휘 범위를 할당과 혼합하는 것은 약간 느슨하게 느껴집니다.

// This...
function Blah() {
   //...
}
Blah.propTypes = {
 thing: PropTypes.string
}
// ...is the same as...
Blah.propTypes = {
 thing: PropTypes.string
}
function Blah() {
   //...
}

// ALTERNATIVELY, here lexical-order is enforced
const Blah = () => {
   //...
}
Blah.propTypes = {
    thing: PropTypes.string
}

그리고 세 번째로, 모든 것이 동일하기 때문에 화살표 기능을 선호합니다.

  • 에게 this, 없습니다.arguments
  • 보기 좋다(임호)
  • 퍼포먼스(지난번에는 화살표 기능이 약간 빨랐습니다)

편집: 메모리 스냅샷

팟캐스트를 듣고 있었는데, 게스트가 메모리 프로파일링으로 화살표 기능을 사용할 수 없는 상황에 대처해야 한다는 이야기를 들었습니다.

현재 메모리 스냅샷에는 변수 이름이 포함되어 있지 않습니다.따라서 메모리 프로파일러를 연결하기 위해 화살표 함수를 명명된 함수로 변환하는 경우가 있습니다.제 경험은 꽤 직설적이고 화살표 기능은 여전히 만족합니다.

또, 메모리 스냅샷을 사용한 것은 1회 뿐이기 때문에, (주관적인) 명료성을 위해서 「계장」을 사용하지 않아도 안심입니다.

다른 스타일 가이드와 마찬가지로 Airbnb는 독단적이고 항상 합리적이지는 않다.

함수의 원래 이름은 최소화 중에 손실되므로 함수 속성은 클라이언트 측 응용 프로그램의 디버깅에만 사용됩니다.디버깅에 관해서는 함수가 콜스택에 의미 있는 이름을 가지고 있지 않으면 효율이 떨어지기 때문에 경우에 따라서는 유지하는 것이 유리합니다.

함수가 취득하다name와 같은 두 가지 기능 정의를 모두 갖추고 있다function Foo = () => {}그리고 화살표처럼 표현이라는 이름의 함수가 있습니다.const Foo = () => {}그 결과,Foo지정된 이름을 가진 함수,Foo.name === 'Foo'.

일부 트랜스필러는 사양을 따릅니다.Babel은 이 코드를 ES5로 변환합니다.

var Foo = function Foo() {};

또한 TypeScript는 다음과 같은 사양을 위반합니다.

var Foo = function () {};

이는 명명된 함수 표현이 나쁘다는 것이 아니므로 권장하지 않아야 한다는 것을 의미합니다.트랜스필러가 사양에 준거하고 있거나 기능명이 문제가 되지 않는 한, 이 문제는 폐기할 수 있습니다.

이 문제는 전치된 어플리케이션에 해당된다.사용 중인 트랜스필러와 기능 유지 필요성에 따라 달라집니다.name소유물.이 문제는 네이티브 ES6에서는 발생하지 않습니다.

그 이유는 다음과 같습니다.

const Listing = ({ hello }) => (
  <div>{hello}</div>
);

에는, 리스트의 유추명이 있습니다만, 이름을 붙이고 있는 것처럼 보이지만, 실제로는, 다음과 같이 되어 있지 않습니다.

// we know the first three ways already...

let func1 = function () {};
console.log(func1.name); // func1

const func2 = function () {};
console.log(func2.name); // func2

var func3 = function () {};
console.log(func3.name); // func3

이건 어때?

const bar = function baz() {
    console.log(bar.name); // baz
    console.log(baz.name); // baz
};

function qux() {
  console.log(qux.name); // qux
}

언급URL : https://stackoverflow.com/questions/37288950/why-does-the-airbnb-style-guide-say-that-relying-on-function-name-inference-is-d