Javascript set const variable inside of a try block

时间:2016-12-02 04:58:53

标签: javascript node.js ecmascript-6 try-catch

Is it possible in ES6 to set a variable inside of a try{} using const in strict mode?

'use strict';

const path = require('path');

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

console.log(configPath);

This fails to lint because configPath is defined out of scope. The only way this seems to work is by doing:

'use strict';

const path = require('path');

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

console.log(configPath);

Basically, is there anyway to use const instead of let for this case?

7 个答案:

答案 0 :(得分:49)

Declaring a variable as const requires you to immediately point it to a value and this reference cannot be changed.

Meaning you cannot define it at one place (outside of try) and assign it a value somewhere else (inside of try).

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

On the other hand, both creating it and giving it a value within the try block is fine.

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

However, const is block-scoped, like let, so if you do create it and give it a value within your try block, it will only exist within that scope.

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

Therefore, if you need to access this variable outside of the try, you must use let:

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

console.log(configPath);

Alternatively, although probably more confusingly, you can use var to create a variable within the try and use it outside of it because var is scoped within the function, not the block (and gets hoisted):

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

console.log(configPath);

答案 1 :(得分:3)

'use strict';

const path = require('path');

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

console.log(configPath);

答案 2 :(得分:1)

我会尝试使用let的临时变量,并在const / try之后将其分配给catch var,并删除临时变量。< / p>

'use strict';

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

const configPath = temp;
temp = undefined;

console.log(configPath);

答案 3 :(得分:0)

Use let. You cannot use const. const does not allow you to reassign the declared constant. While it is generally good practice to declare objects like yours with const, the entire point of doing so is to allow objects to be mutated without allowing them to be reassigned. You are reassigning the object (thus, defeating the purpose of const), so use let instead.

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

答案 4 :(得分:0)

这里有很多好的答案。但是,必须将您的租约管理在范围之内和之外,这确实很烦人。因此,如果您像我一样,并且来到这里寻找更好的模式。我写了一个小工具,可以帮助很多人。

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
      },
    })
  })
})

答案 5 :(得分:0)

除了我在这里看到的 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 可能更简洁,但我只是想指出另一种可能的选择。

答案 6 :(得分:0)

如果函数是异步的,你可以完全避免 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