Javascript 是否可以创建一个命名的;“胖箭”;打字稿中的lambda?

Javascript 是否可以创建一个命名的;“胖箭”;打字稿中的lambda?,javascript,lambda,typescript,arrow-functions,Javascript,Lambda,Typescript,Arrow Functions,使用传统的函数语法,可以内联创建命名函数 var fn = function myName(arg) { // whatever }; // fn.name === "myName" 可以使用lambda语法在typescript中指定名称吗 var fn = (arg) => { // whatever }; // fn.name not set 看起来您无法做到这一点,因为没有介绍它,只是在“deferred”下面的末尾,它声明了“命名箭头函数表达式的可选前导标识符

使用传统的函数语法,可以内联创建命名函数

var fn = function myName(arg) {
    // whatever
};
// fn.name === "myName"
可以使用lambda语法在typescript中指定名称吗

var fn = (arg) => {
    // whatever
};
// fn.name not set

看起来您无法做到这一点,因为没有介绍它,只是在“deferred”下面的末尾,它声明了“命名箭头函数表达式的可选前导标识符”。

是的,但有点棘手

arrow函数从分配给它的变量中获取名称。它被称为名称是从该变量推断出来的(在您的例子中是
fn.name==“fn”
)。有一些限制,因为这样的名称不能作为常规标识符使用,因此不能从函数本身内部使用(用于递归或事件解除绑定)

如果使用以下代码:

const joeThrows = (thing: string):never => {
  throw new Error(`Joe took ${thing} and throwed it at you.`);
}

const simonThrows = ({
  simonSays: (what: string):never => {
    throw new Error(`Simon said ${what} and throwed you out.`);
  }
})["simonSays"];


try {
  console.log("== joeThrows fat-arrow %s has name '%s' ==", typeof joeThrows, joeThrows.name);
  joeThrows("hammer");
} catch(ex) { console.log(ex.stack); }

try {
  console.log("=== simonThrows fat-arrow %s has name '%s' ==", typeof simonThrows, simonThrows.name);
  simonThrows("I have a name!");
} catch(ex) { console.log(ex.stack); }
然后您将获得以下输出:

=== joeThrows fat-arrow function has name 'joeThrows' ==
Joe took hammer and throwed it at you.
Error: Joe took hammer and throwed it at you.
    at joeThrows (/code-demo/named.js:2:11)
    at Object.<anonymous> (/code-demo/named.js:11:5)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    ...
=== simonThrows fat-arrow function has name 'simonSays' ==
Error: Simon said I have a name! and throwed you out.
    at simonSays (/code-demo/named.js:6:15)
    at Object.<anonymous> (/code-demo/named.js:18:5)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    ...
==joeThrows胖箭头函数的名称为“joeThrows”==
乔拿起锤子朝你扔去。
错误:乔拿起锤子朝你扔去。
在joeThrows(/code-demo/named.js:2:11)
反对。(/code-demo/named.js:11:5)
at模块编译(内部/modules/cjs/loader.js:778:30)
...
===simonThrows fat arrow函数的名称为“simonSays”==
错误:西蒙说我有名字!把你扔出去。
在simonSays(/code-demo/named.js:6:15)
反对。(/code-demo/named.js:18:5)
at模块编译(内部/modules/cjs/loader.js:778:30)
...
我很少在对象字段赋值和读取表达式中使用第二种技术

当您想要创建更多的函数,这些函数将作为具有相同功能的回调函数,用于不同的设置,并且您想要更精确地可视化异常源,而不只是使用一个通用名称时,这将非常方便。例如,要动态创建Redux选择器或FeatherJS钩子,这些钩子非常通用,可以通过函数创建者的参数进行自定义:

// Let's suppose we have the types
type HookContext = Record<string, any>;
type ServiceHook = (context: HookContext) => HookContext;

// Then we can define service hook factory function
export const createServiceHook = (purpose: string): ServiceHook => {
    const fn = `serviceHook$${purpose}`;
    return ({
        [fn]: (context: HookContext): HookContext => {
            // Do something here with the context which may throw exception
            return context;
        }
    })[fn];
};

// Later we can create a specific hook function instance that:
// * will have lookoutForSummer.name equal to "serviceHook$summer"
// * will show that name in call-stack in case exception is throw
export const lookoutForSummer = createServiceHook("summer");

//假设我们有类型
类型HookContext=记录;
输入ServiceHook=(上下文:HookContext)=>HookContext;
//然后我们可以定义服务钩子工厂函数
export const createServiceHook=(目的:字符串):ServiceHook=>{
const fn=`serviceHook$${purpose}`;
返回({
[fn]:(上下文:HookContext):HookContext=>{
//在这里使用可能引发异常的上下文执行某些操作
返回上下文;
}
})[fn];
};
//稍后,我们可以创建一个特定的钩子函数实例:
//*将lookoutForSummer.name设置为“serviceHook$summer”
//*将在抛出异常时在调用堆栈中显示该名称
export const lookoutorsummer=createServiceHook(“夏季”);

正确。仅供参考,未安装的原因是ES6不支持