「先端面接問題シリーズ5」ES 6における矢印関数の使い方

4737 ワード

前言


年が経つにつれて、気持ちを片付けて、コードを叩き続けましょう.
金三銀四の就職シーズンが近づいていることについて、多くの学生が黙って準備をしていると信じています.このシリーズは、先端の膨大な知識点を整理し、できるだけ分かりやすく表現することを目的としており、必要な学生にも役立つことを望んでいます.
これは先端試験問題シリーズの5編目です.前の章を逃したかもしれません.ここで見つけることができます.
  • thisの原理及び用法
  • 偽類と偽元素の区別及び実戦
  • どのようにして聖杯のレイアウトを実現しますか?
  • 今日のトップ面接問題と構想解析
  • 面接では、ES 6の知識点をよく聞きます.普段は仕事でたくさん使っているからです.矢印関数を聞くと、多くの候補者が「矢印関数は使いやすく、これ以上この指向を心配する必要はない」と感嘆する.
    矢印関数は使いやすいですが、矢印関数を使うのに向いていないシーンに遭遇したことがありますか?
    この時、答えられる候補者は少ない.矢印関数はほとんどの場合、使いやすいですが、矢印関数を使用すると問題が発生するシーンがあります.矢印関数がまだ十分ではありませんか?また、どのようなシーンで問題が発生しますか?どうやって解決すればいいですか?これは、本稿で一緒に検討したいことです.

    矢印関数の書き方


    矢印関数(Arrow Function)とは何ですか?その書き方は矢印のように見えます.
    const multiply = num => num * num;

    これは次のようなものです.
    const multiply = function (num) {
        return num * num;
    };

    また、複数のパラメータ、および可変パラメータを伝達することもできる.
    //    
    const multiply = (num1, num2) => num1 * num2;
    
    //     
    const sum = (num1, num2, ...rest) => {
        let result = num1 + num2;
        for (let i = 0; i < rest.length; i++) {
            result += rest[i];
        }
        
        return result;
    };

    複数の文がある場合は、{...}returnを付ける必要があります.
    また、返される結果がオブジェクトであれば、()を付ける必要があります.以下のようにします.
    const func = val => ({ value: val });

    上記の書き方から見ると,矢印関数は通常の関数に比べて確かに簡便であり,我々のコードの使いやすさを向上させた.ただし、どのシーンでも適用されるわけではありません.次に、矢印関数に合わないシーンをいくつか紹介し、実行可能な解決策を提案します.

    ふさわしくないシーン


    1、対象の方法


    次の例を見てください.
    const obj = {
        x: 1,
        print: () => {
            console.log(this === window); // => true
            console.log(this.x); // undefined
        }
    };
    
    obj.print();

    this.x印刷はundefinedです.どうして?そして、私は上に行を追加して、thisがwindowを指していることに気づきました.
    解析:printメソッドは矢印関数を用いて、その内部のthisはやはりコンテキストwindowを指して、コンテキストの中でxを定義していないので、this.x出力はundefinedです.
    解決策:ES 6のフレーズ法、あるいは伝統的な関数式でもいいです.だからprintはこう書きます.
    print () {
        console.log(this === test); // => true
        console.log(this.x); // 1
    }

    2、原型方法


    同じルールはプロトタイプメソッドの定義にも適用され、矢印関数を使用すると実行時の実行コンテキストエラーが発生します.
    function Cat (name) {
        this.name = name;
    }
    
    Cat.prototype.sayCatName = () => {
        console.log(this === window); // => true
        return this.name;
    };
    
    const cat = new Cat('Miao');
    cat.sayCatName(); // => undefined

    解決策は、従来の関数式に戻ることです.次のようにします.
    Cat.prototype.sayCatName = function () {
        console.log(this === cat); // => true
        return this.name;
    };

    sayCatNameが従来の関数式に戻ると、呼び出された実行コンテキストは新しく作成されたcatインスタンスを指します.

    3、イベントのコールバック


    次の例を見てください.
    const btn = document.getElementById('myButton');
    btn.addEventListener('click', () => {
      console.log(this === window); // => true
      this.innerHTML = 'Clicked button';
    });

    ここで問題があります.これはwindowを指しているからです.
    解析:DOMイベントにコールバック関数をバインドした後、コールバック関数をトリガーする場合のthisは、現在発生しているイベントのDOMノード、すなわちここのbtnを指す必要があります.コールバックが発生すると、ブラウザはbtnのコンテキストで処理関数を呼び出します.だから最後のthis.innerHTMLはwindowに等しい.innerHTML、問題はここにあります.
    解決策:矢印関数の代わりに関数式を使用します.このように:
    btn.addEventListener('click', function() {
        console.log(this === btn); // => true
        this.innerHTML = 'Clicked button';
    });

    またreactでのイベントコールバックも,類似の問題に遭遇することが多い.
    // jsx render
    
    
    // callback
    handleClickButton () {
        ...
    }

    注意:ここでonClickのコールバック関数は、文字列ではなく、実質的な関数です.onClickは中間変数として理解できるので、reactが関数を処理するときのthis指向は失われます.
    この問題を解決するために、イベント処理関数がどのように伝達されるか、インスタンス化されたオブジェクトを指すように、コールバック関数にthisをバインドする必要があります.
    ここで、矢印関数を使用すると、次のように書き換えることができます.

    矢印関数にはthisはありませんので、イベント処理関数の呼び出し者は影響を受けません.

    4、コンストラクタ


    矢印関数はnewキーワードで呼び出せません.
    const Message = (text) => {
        this.text = text;
    };
    
    var helloMessage = new Message('Hello World!');
    // Uncaught TypeError: Message is not a constructor

    解析:エラーメッセージから,矢印関数にはconstructorメソッドがないため,構造関数として使用できないことがわかる.JavaScriptは、異常を投げ出すことで暗黙的に予防します.
    解決方法:矢印関数の代わりに関数式を使用します.

    まとめ


    MDNが与えた解釈を振り返る:矢印関数式の文法は関数式より短く、自分のthis、arguments、superまたはnewがない.target.これらの関数式は、匿名関数が必要な場所に適しており、構造関数として使用できません.
    したがって,矢印関数は間違いなくES 6による重大な改良であり,正しい場合に矢印関数を用いることで,コードをより簡潔で短くすることができる.しかし、矢印関数も万能ではありません.使えないときは、無理にカバーしないでください.たとえば、ダイナミックコンテキストが必要なシーンでは、矢印関数を使用するには、オブジェクトのメソッド、プロトタイプメソッド、イベントのコールバック、コンストラクション関数など、注意が必要です.問題を解決するには、矢印関数を使用する必要はありません.
    PS:私の公衆番号「超兄先端小桟」に注目して、もっと多くの考えと技術を交流してください.