繁体   English   中英

Javascript 在 try 块内设置 const 变量

[英]Javascript set const variable inside of a try block

ES6中是否可以在严格模式下使用consttry{}中设置变量?

'use strict';

const path = require('path');

try {
    const configPath = path.resolve(process.cwd(), config);
} catch(error) {
    //.....
}

console.log(configPath);

这无法检查,因为configPath是在 scope 之外定义的。这似乎唯一可行的方法是:

'use strict';

const path = require('path');

let configPath;
try {
    configPath = path.resolve(process.cwd(), config);
} catch(error) {
    //.....   
}

console.log(configPath);

基本上,对于这种情况,有什么方法可以使用const而不是let吗?

将变量声明为const要求您立即将其指向一个值,并且此引用无法更改。

这意味着你不能在一个地方(外定义它try )和其他(内部的某个地方给它分配一个值try )。

 const test; // Syntax Error try { test = 5; } catch(err) {}

另一方面,在try块中创建它并给它一个值都很好。

 try { const test = 5; // this is fine } catch(err) {}

然而, const是块范围的,就像let一样,所以如果你创建它并在你的try块中给它一个值,它只会存在于那个范围内。

 try { const test = 5; // this is fine } catch(err) {} console.log(test); // test doesn't exist here

因此,如果您需要在try之外访问此变量,则必须使用let

let configPath;
try {
   configPath = path.resolve(process.cwd(), config);
} catch(error) {
    //.....   
}

console.log(configPath);

或者,虽然可能更令人困惑,但您可以使用vartry创建一个变量并在它之外使用它,因为var范围在函数内,而不是块内(并被提升):

try {
   var configPath = path.resolve(process.cwd(), config);
} catch(error) {
    //.....   
}

console.log(configPath);
'use strict';

const path = require('path');

const configPath = (function() {
  try {
    return path.resolve(process.cwd(), config);
  } catch (error) {
    //.....
  }
})()

console.log(configPath);

我会尝试将临时变量与let一起使用,并在try / catch和“删除”临时变量之后将其分配给const var。

'use strict';

let temp;
try {
  temp = path.resolve(process.cwd(), config);
} catch (error) {
  //.....   
}

const configPath = temp;
temp = undefined;

console.log(configPath);

这里有很多很好的答案。 但是必须管理您的允许在范围内和范围外确实很烦人。 所以如果你和我一样,来到这里寻找更好的模式。 我写了一个小实用程序,可以帮助很多。

export const tc = <T>(option: { try: () => T; catch: (e: Error) => T }) => {
  try {
    return option.try()
  } catch (e) {
    return option.catch(e)
  }
}

这里有一些单元测试来展示它是如何有用的

import { tc } from './tc'
describe('tc', () => {
  it('should return successfully', () => {
    const result = tc({
      try: () => 1 + 2,
      catch: () => -1,
    })
    expect(result).toEqual(3)
  })
  it('should catch', () => {
    const spy = jest.fn()
    const result = tc({
      try: (): number => {
        throw new Error('Test')
      },
      catch: (e) => {
        spy()
        expect(e.message).toEqual('Test')
        return -1
      },
    })
    expect(spy).toHaveBeenCalledTimes(1)
    expect(result)
  })
  it('should rethrow', () => {
    expect(() =>
      tc({
        try: (): number => {
          throw new Error('Test')
        },
        catch: (e) => {
          throw e
        },
      }),
    ).toThrowError()
  })
  it('should have proper types', () => {
    // @ts-expect-error
    const result: string = tc({
      try: () => 12,
      catch: (e) => {
        return -1
      },
    })
  })
})

除了我在这里看到的let选项之外,另一个选项可能是使用对象,因为对对象的引用是常量,但它的属性可以改变,所以像这样:

'use strict';

const path = require('path');

const configPath = { value: null };

try {
    configPath.value = path.resolve(process.cwd(), config);
} catch(error) {
    //.....
}

console.log(configPath.value);

坚持使用 let 可能会更清晰,但我只是想指出另一种可能的选择。

如果函数是异步的,你可以完全避免 try 块! 今天刚学会这个,我想我会分享!

更广泛地适用于您的情况,因为这是“const in a try block”的最佳 Google 结果

use strict';
const path = require('path');

const getPath = async () => {
    return path.resolve(process.cwd())
}

const logPath = async () => {
    const configPath = await getPath().catch(e => console.log(e)) <--avoid the try
    console.log(configPath);
}

logPath()

当您已经在异步函数中并且需要等待其他事情时,效果很好:

async function main() {
  const result = await asyncTask().catch(error => console.error(error));
}

学习自: https : //stackoverflow.com/a/55024396/2936521

你可以这样做:


  const result = await promise.catch(err=>{
    console.log(err)
  })

使用let 您不能使用const const不允许您重新分配声明的常量。 虽然使用const声明像您这样的对象通常是一种很好的做法,但这样做全部意义在于允许对象发生变异而不允许重新分配它们。 您正在重新分配对象(因此,违背了const的目的),因此请改用let

let path = require('path');
// Good to go!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM