How do I write a named arrow function in ES2015?

前端 未结 8 823
余生分开走
余生分开走 2020-11-22 16:29

I have a function that I am trying to convert to the new arrow syntax in ES6. It is a named function:

function sayHello(name) {
    console         


        
相关标签:
8条回答
  • 2020-11-22 16:46

    It appears that this will be possible with ES7: https://babeljs.io/blog/2015/06/07/react-on-es6-plus#arrow-functions

    The example given is:

    class PostInfo extends React.Component {
      handleOptionsButtonClick = (e) => {
        this.setState({showOptionsModal: true});
      }
    }
    

    The body of ES6 arrow functions share the same lexical this as the code that surrounds them, which gets us the desired result because of the way that ES7 property initializers are scoped.

    Note that to get this working with babel I needed to enable the most experimental ES7 stage 0 syntax. In my webpack.config.js file I updated the babel loader like so:

    {test: /\.js$/, exclude: /node_modules/, loader: 'babel?stage=0'},
    
    0 讨论(0)
  • 2020-11-22 16:47

    Actually it looks like one way to name arrow functions (at least as of chrome 77...) is to do this:

    "use strict";
    let fn_names = {};
    fn_names.foo = () => { throw new Error(); };
    console.log("foo.name is: " + foo.name);
    try {
      foo();
    } catch (e) {
      console.log(e.stack);
    }
    

    0 讨论(0)
  • 2020-11-22 16:59

    THIS IS ES6

    Yeah I think what you're after is something like this:

    const foo = (depth) => {console.log("hi i'm Adele")}
    foo -> // the function itself
    foo() -> // "hi i'm Adele"
    
    0 讨论(0)
  • 2020-11-22 17:01

    If by 'named', you mean you want the .name property of your arrow function to be set, you're in luck.

    If an arrow function is defined on the right-hand-side of an assignment expression, the engine will take the name on the left-hand-side and use it to set the arrow function's .name, e.g.

    var sayHello = (name) => {
        console.log(name + ' says hello');
    }
    
    sayHello.name //=== 'sayHello'
    

    Having said that, your question seems to be more 'can I get an arrow function to hoist?'. The answer to that one is a big ol' "no", I'm afraid.

    0 讨论(0)
  • 2020-11-22 17:01

    in order to write named arrow function you can fellow the bellow example, where I have a class named LoginClass and inside this class I wrote an arrow named function, named successAuth class LoginClass {

        constructor() {
    
        }
    
        successAuth = (dataArgs)=> { //named arow function
    
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 17:03

    How do I write a named arrow function in ES2015?

    You do it the way you ruled out in your question: You put it on the right-hand side of an assignment or property initializer where the variable or property name can reasonably be used as a name by the JavaScript engine. There's no other way to do it, but doing that is correct and fully covered by the specification.

    Per spec, this function has a true name, sayHello:

    var sayHello = name => {
        console.log(name + ' says hello');
    };
    

    This is defined in Assignment Operators > Runtime Semantics: Evaluation where it calls the abstract SetFunctionName operation (that call is currently in step 1.e.iii).

    Similiarly, Runtime Semantics: PropertyDefinitionEvaluation calls SetFunctionName and thus gives this function a true name:

    let o = {
        sayHello: name => {
            console.log(`${name} says hello`);
        }
    };
    

    Modern engines set the internal name of the function for statements like that already; Edge still has the bit making it available as name on the function instance behind a runtime flag.

    For example, in Chrome or Firefox, open the web console and then run this snippet:

    "use strict";
    let foo = () => { throw new Error(); };
    console.log("foo.name is: " + foo.name);
    try {
      foo();
    } catch (e) {
      console.log(e.stack);
    }

    On Chrome 51 and above and Firefox 53 and above (and Edge 13 and above with an experimental flag), when you run that, you'll see:

    foo.name is: foo
    Error
        at foo (http://stacksnippets.net/js:14:23)
        at http://stacksnippets.net/js:17:3
    

    Note the foo.name is: foo and Error...at foo.

    On Chrome 50 and earlier, Firefox 52 and earlier, and Edge without the experimental flag, you'll see this instead because they don't have the Function#name property (yet):

    foo.name is: 
    Error
        at foo (http://stacksnippets.net/js:14:23)
        at http://stacksnippets.net/js:17:3
    

    Note that the name is missing from foo.name is:, but it is shown in the stack trace. It's just that actually implementing the name property on the function was lower priority than some other ES2015 features; Chrome and Firefox have it now; Edge has it behind a flag, presumably it won't be behind the flag a lot longer.

    Obviously, I can only use this function after I have defined it

    Correct. There is no function declaration syntax for arrow functions, only function expression syntax, and there's no arrow equivalent to the name in an old-style named function expression (var f = function foo() { };). So there's no equivalent to:

    console.log(function fact(n) {
        if (n < 0) {
            throw new Error("Not defined for negative numbers");
        }
        return n == 0 ? 1 : n * fact(n - 1);
    }(5)); // 120

    You have to break it into two expressions (I'd argue you should do that anyway):

    const fact = n => {
        if (n < 0) {
            throw new Error("Not defined for negative numbers.");
        }
        return n == 0 ? 1 : n * fact(n - 1);
    };
    console.log(fact(5));

    Of course, if you have to put this where a single expression is required, you can always...use an arrow function:

    console.log((() => {
        const fact = n => {
            if (n < 0) {
                throw new Error("Not defined for negative numbers.");
            }
            return n == 0 ? 1 : n * fact(n - 1);
        };
        return fact(5);
    })()); // 120

    I ain't sayin' that's pretty, but it works if you absolutely, positively need a single expression wrapper.

    0 讨论(0)
提交回复
热议问题