웹 프론트엔드 JS 튜토리얼 화살표 기능 이해

화살표 기능 이해

Jun 16, 2020 am 09:41 AM
js

나는 이미 화살표 기능을 아주 잘 이해했고 다시는 속지 않을 거라고 느꼈던 적이 있습니다. 그런데 며칠 전 아주 이상한 문제에 부딪혔습니다. 오랫동안 고민한 결과 화살표 기능으로 인한 함정이라는 것을 알게 되었습니다. 그래서 이런 글이 있군요~

문제 설명

예를 들어 기본 메서드인 sayName을 갖는 기본 클래스인 Animal이 있습니다. 이를 상속받는 각 후속 하위 클래스는 해당 ID를 증명하기 위해 sayName 메서드를 구현해야 합니다. 기본 클래스 코드 구현은 매우 간단합니다.

class Animal {
	sayName = () => {
		throw new Error('你应该自己实现这个方法');
  }
}
로그인 후 복사

이제 Animal 기본 클래스에서 상속하여 Pig 하위 클래스를 구현해야 합니다. 구현도 매우 간단합니다.

class Pig extends Animal {
	sayName() {
		console.log('I am a Pig');
	}
}
로그인 후 복사

이봐, 너무 간단해? 함정은 어디에 있습니까? 그러나 실제로 실행해 보면 결과가 예상과 다르다는 것을 알 수 있습니다.

화살표 기능 이해

야, 이게 왜 이래? 정확히 무엇이 잘못되었나요? 이 짧은 몇 줄의 코드가 오류를 보고하는 이유는 무엇입니까?

문제 발견

많은 고민 끝에 마침내 화살표 기능의 함정이라는 것을 알게 되었습니다. 이 문제를 해결하려면 Animal 기본 클래스의 sayName을 일반 함수로 변경하거나 Pig 하위 클래스의 sayName을 화살표 함수로 변경하기만 하면 됩니다. 그렇다면 화살표 기능에서는 정확히 무슨 일이 벌어지고 있는 걸까요?

이 글을 쓰면서 문득 한 번 이 질문에 대해 면접관에게 인터뷰를 했던 기억이 나네요! 당시 면접관은 클래스의 생성자에 있는 화살표 함수와 클래스의 일반 함수, 바인드 함수의 차이점에 대해 질문했습니다. 당시에는 대답이 명확하고 논리적이었지만 상속에 관해서는 모든 것이 뒤집어졌습니다. 그럼 위의 질문에 답하기 위해 먼저 면접 질문에 답해보겠습니다.

화살표 함수와 일반 함수, 생성자 내 바인드 함수의 차이점은 무엇인가요?

이 문제를 보다 직관적으로 확인하기 위해 Babel의 코드 컴파일 결과를 사용하면 차이점을 더 잘 확인할 수 있습니다.

먼저 간단한 코드를 입력해 보겠습니다

class A {
  	constructor() {
		this.b = this.b.bind(this);    	
    }
  
    a() {
    	console.log('a');
    }
	  b() {
    	console.log('b')
    }
    c = () => {
    	console.log('c')
    }
}
로그인 후 복사

babel이 컴파일할 때 어떤 모습일지 살펴보겠습니다.

"use strict";

function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }

function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var A = /*#__PURE__*/function () {
  function A() {
    _classCallCheck(this, A);

    _defineProperty(this, "c", function () {
      console.log(&#39;c&#39;);
    });

    this.b = this.b.bind(this);
  }

  _createClass(A, [{
    key: "a",
    value: function a() {
      console.log(&#39;a&#39;);
    }
  }, {
    key: "b",
    value: function b() {
      console.log(&#39;b&#39;);
    }
  }]);

  return A;
}();
로그인 후 복사

컴파일된 코드의 대부분은 보조 함수이므로 핵심 부분만 볼 수 있습니다.

var A = /*#__PURE__*/function () {
  function A() {
    _classCallCheck(this, A);

    _defineProperty(this, "c", function () {
      console.log(&#39;c&#39;);
    });

    this.b = this.b.bind(this);
  }

  _createClass(A, [{
    key: "a",
    value: function a() {
      console.log(&#39;a&#39;);
    }
  }, {
    key: "b",
    value: function b() {
      console.log(&#39;b&#39;);
    }
  }]);

  return A;
}();
로그인 후 복사

컴파일된 결과에서 이들 간의 차이점을 볼 수 있습니다.

  • 일반 함수: babel이 컴파일된 후 함수의 프로토타입에 배치됩니다.

  • 생성자의 바인드 함수: 컴파일 후, is는 함수의 프로토타입에 배치될 뿐만 아니라 인스턴스화될 때마다 현재 인스턴스 컨텍스트에 바인딩된 변수가 생성됩니다(this.b = this.b.bind(this)).

  • Arrow 함수: babel이 컴파일된 후 인스턴스화될 때마다 DefineProperty가 호출되어 화살표 함수 내용을 현재 인스턴스 컨텍스트에 바인딩합니다.

컴파일된 결과로 볼 때 실제 개발을 위해 컨텍스트 바인딩이 필요한 경우 화살표 기능을 사용하는 것이 가장 좋습니다. 바인드 메소드를 사용하면 프로토타입 함수뿐만 아니라 각 인스턴스화에 대한 추가 함수도 생성되기 때문입니다.

Update

Yu Tengjing의 댓글을 읽은 후 더 중요한 것을 배웠습니다.

class = 기호로 선언된 메서드와 변수는 인스턴스의 속성으로 사용되고, = 기호 없이 선언된 속성은 프로토타입 체인에 배치됩니다. 예를 들어

class A {
    a() {
        
    }
    b = 2;
    c = () => {
    }
}
로그인 후 복사

이 클래스의 경우 인스턴스화되면 b와 c가 인스턴스의 속성으로 사용되고 a는 프로토타입 체인에 배치됩니다.

그렇다면 왜 이것이 달성되는 걸까요? 실제로 tc39 사양에서 이것이 언급되어 있음을 볼 수 있습니다: 필드 선언

등호 선언이 직접 작성된 인스턴스의 경우 실제로는 필드 선언의 구문이며 이러한 인스턴스 속성을 직접 선언하는 것과 동일합니다.

주제로 돌아가기

이전 질문을 해결한 후 다시 주제로 돌아가겠습니다. 실제 컴파일 조건에서 클래스의 화살표 함수의 컴파일 결과를 이해하고 나면 실제로 문제를 이해하는 것이 더 쉽습니다.

Q: 하위 클래스가 일반 함수를 사용하여 sayName을 선언하면 실행 문제가 발생하는 이유는 무엇입니까?

A: 서브클래스가 일반 함수를 사용하여 sayName을 선언하는 경우 서브클래스에서 선언한 sayName은 생성자의 프로토타입에 배치됩니다. 그러나 기본 클래스의 sayName은 화살표 함수를 사용하므로 각 인스턴스에는 직접 sayName 변수가 있습니다. 자바스크립트 변수의 접근 규칙에 따라 변수 자체를 먼저 검색하고, 찾을 수 없으면 프로토타입 체인에서 검색하게 됩니다. 따라서 sayName을 검색하면 기본 클래스에서 선언한 sayName 함수를 직접 찾게 되고, 프로토타입 체인에서는 찾지 않으므로 문제가 발생한다.

Q: 하위 클래스가 sayName을 선언하기 위해 화살표 함수를 사용하는 이유는 무엇입니까? 실행에는 문제가 없습니다.

A: es6 클래스가 초기화되면 먼저 기본 클래스의 생성자를 실행한 다음 자체 생성자를 실행합니다. 따라서 기본 클래스가 초기화된 후에는 하위 클래스에서 선언한 화살표 함수 sayName이 기본 클래스의 화살표 함수를 재정의하므로 실행에는 문제가 없습니다.

요약

한때 화살표 기능을 잘 안다고 생각했는데, 역시 배움에는 끝이 없군요! 그러나 나는 또한 클래스 내 화살표 기능에 대해 더 깊이 이해하고 있습니다.

그러나 댓글 영역의 모든 사람들에게 상기시켜 준 결과 실제로는 화살표 함수로 인해 문제가 발생하지 않는다는 것을 알았습니다. = 기호 클래스로 선언된 변수는 Field 선언의 구문에 속합니다. 이런 방식으로 선언된 변수의 경우 프로토타입 체인에 마운트되는 대신 인스턴스의 속성에 직접 마운트됩니다.

추천 튜토리얼: "JS Tutorial"

위 내용은 화살표 기능 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

JS 및 Baidu Maps를 사용하여 지도 이동 기능을 구현하는 방법 JS 및 Baidu Maps를 사용하여 지도 이동 기능을 구현하는 방법 Nov 21, 2023 am 10:00 AM

JS 및 Baidu Map을 사용하여 지도 팬 기능을 구현하는 방법 Baidu Map은 지리 정보, 위치 지정 및 기타 기능을 표시하기 위해 웹 개발에 자주 사용되는 널리 사용되는 지도 서비스 플랫폼입니다. 이 글에서는 JS와 Baidu Map API를 사용하여 지도 이동 기능을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. 준비 바이두 맵 API를 사용하기 전에 먼저 바이두 맵 오픈 플랫폼(http://lbsyun.baidu.com/)에서 개발자 계정을 신청하고 애플리케이션을 만들어야 합니다. 생성 완료

권장 사항: 우수한 JS 오픈 소스 얼굴 감지 및 인식 프로젝트 권장 사항: 우수한 JS 오픈 소스 얼굴 감지 및 인식 프로젝트 Apr 03, 2024 am 11:55 AM

얼굴 검출 및 인식 기술은 이미 상대적으로 성숙하고 널리 사용되는 기술입니다. 현재 가장 널리 사용되는 인터넷 응용 언어는 JS입니다. 웹 프런트엔드에서 얼굴 감지 및 인식을 구현하는 것은 백엔드 얼굴 인식에 비해 장점과 단점이 있습니다. 장점에는 네트워크 상호 작용 및 실시간 인식이 줄어 사용자 대기 시간이 크게 단축되고 사용자 경험이 향상된다는 단점이 있습니다. 모델 크기에 따라 제한되고 정확도도 제한됩니다. js를 사용하여 웹에서 얼굴 인식을 구현하는 방법은 무엇입니까? 웹에서 얼굴 인식을 구현하려면 JavaScript, HTML, CSS, WebRTC 등 관련 프로그래밍 언어 및 기술에 익숙해야 합니다. 동시에 관련 컴퓨터 비전 및 인공지능 기술도 마스터해야 합니다. 웹 측면의 디자인으로 인해 주목할 가치가 있습니다.

PHP와 JS를 사용하여 주식 촛대 차트를 만드는 방법 PHP와 JS를 사용하여 주식 촛대 차트를 만드는 방법 Dec 17, 2023 am 08:08 AM

PHP와 JS를 사용하여 주식 캔들 차트를 만드는 방법 주식 캔들 차트는 주식 시장에서 흔히 사용되는 기술 분석 그래픽으로 시가, 종가, 최고가 등의 데이터를 그려서 투자자가 주식을 보다 직관적으로 이해할 수 있도록 도와줍니다. 주식의 최저 가격. 이 기사에서는 특정 코드 예제와 함께 PHP 및 JS를 사용하여 주식 캔들 차트를 만드는 방법을 설명합니다. 1. 준비 시작하기 전에 다음 환경을 준비해야 합니다. 1. PHP를 실행하는 서버 2. HTML5 및 Canvas를 지원하는 브라우저 3

주식 분석을 위한 필수 도구: PHP 및 JS를 사용하여 캔들 차트를 그리는 단계를 알아보세요. 주식 분석을 위한 필수 도구: PHP 및 JS를 사용하여 캔들 차트를 그리는 단계를 알아보세요. Dec 17, 2023 pm 06:55 PM

주식 분석을 위한 필수 도구: PHP 및 JS에서 캔들 차트를 그리는 단계를 배우십시오. 인터넷과 기술의 급속한 발전으로 주식 거래는 많은 투자자에게 중요한 방법 중 하나가 되었습니다. 주식분석은 투자자의 의사결정에 있어 중요한 부분이며 캔들차트는 기술적 분석에 널리 사용됩니다. PHP와 JS를 사용하여 캔들 차트를 그리는 방법을 배우면 투자자가 더 나은 결정을 내리는 데 도움이 되는 보다 직관적인 정보를 얻을 수 있습니다. 캔들스틱 차트는 주가를 캔들스틱 형태로 표시하는 기술 차트입니다. 주가를 보여주네요

JS와 Baidu Map을 활용하여 지도 클릭 이벤트 처리 기능을 구현하는 방법 JS와 Baidu Map을 활용하여 지도 클릭 이벤트 처리 기능을 구현하는 방법 Nov 21, 2023 am 11:11 AM

JS 및 Baidu Maps를 사용하여 지도 클릭 이벤트 처리 기능을 구현하는 방법 개요: 웹 개발에서는 지리적 위치 및 지리적 정보를 표시하기 위해 지도 기능을 사용해야 하는 경우가 많습니다. 지도에서의 클릭 이벤트 처리는 지도 기능에서 일반적으로 사용되는 중요한 부분입니다. 이 글에서는 JS와 Baidu Map API를 사용하여 지도의 클릭 이벤트 처리 기능을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 단계: Baidu Map API 파일 가져오기 먼저 다음 코드를 통해 Baidu Map API 파일을 가져올 수 있습니다.

JS 및 Baidu Maps를 사용하여 지도 히트맵 기능을 구현하는 방법 JS 및 Baidu Maps를 사용하여 지도 히트맵 기능을 구현하는 방법 Nov 21, 2023 am 09:33 AM

JS 및 Baidu Maps를 사용하여 지도 열 지도 기능을 구현하는 방법 소개: 인터넷과 모바일 장치의 급속한 발전으로 지도는 일반적인 응용 시나리오가 되었습니다. 시각적 표시 방법인 히트맵은 데이터 분포를 보다 직관적으로 이해하는 데 도움이 될 수 있습니다. 이 기사에서는 JS 및 Baidu Map API를 사용하여 지도 히트맵 기능을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 준비 작업: 시작하기 전에 Baidu 개발자 계정, 애플리케이션 생성, 해당 AP 획득 등의 항목을 준비해야 합니다.

PHP 및 JS 개발 팁: 주식 캔들 차트 그리기 방법 익히기 PHP 및 JS 개발 팁: 주식 캔들 차트 그리기 방법 익히기 Dec 18, 2023 pm 03:39 PM

인터넷 금융의 급속한 발전으로 인해 주식 투자는 점점 더 많은 사람들의 선택이 되었습니다. 주식 거래에서 캔들 차트는 주가의 변화 추세를 보여주고 투자자가 보다 정확한 결정을 내리는 데 도움이 되는 일반적으로 사용되는 기술적 분석 방법입니다. 이 기사에서는 PHP와 JS의 개발 기술을 소개하고 독자가 주식 캔들 차트를 그리는 방법을 이해하도록 유도하며 구체적인 코드 예제를 제공합니다. 1. 주식 캔들 차트의 이해 주식 캔들 차트를 그리는 방법을 소개하기 전에 먼저 캔들 차트가 무엇인지부터 이해해야 합니다. 캔들스틱 차트는 일본인이 개발했습니다.

js와 vue의 관계 js와 vue의 관계 Mar 11, 2024 pm 05:21 PM

js와 vue의 관계: 1. 웹 개발의 초석인 JS 2. 프론트엔드 프레임워크로서의 Vue.js의 등장 3. JS와 Vue의 상호 보완적인 관계 4. JS와 Vue의 실제 적용 Vue.

See all articles