Javascript 实例变量与模块作用域变量

Javascript 实例变量与模块作用域变量,javascript,reactjs,Javascript,Reactjs,以下组件将产生相同的结果: const currYear = Date.now().getFullYear(); class App extends React.Component { render() { return <MyComponent year={currYear} />; } }; const currYear=Date.now().getFullYear(); 类应用程序扩展了React.Component{ render(){ 返回; } };

以下组件将产生相同的结果:

const currYear = Date.now().getFullYear();

class App extends React.Component {
  render() {
    return <MyComponent year={currYear} />;
  }
};
const currYear=Date.now().getFullYear();
类应用程序扩展了React.Component{
render(){
返回;
}
};

类应用程序扩展了React.Component{
构造函数(){
超级();
this.currYear=Date.now().getFullYear();
}
render(){
返回;
}
};
假设变量从未改变

它们的应用是否可以被认为是等效的?
如果没有,是否存在一种方法优于另一种方法的情况


好奇了很长时间,但从未找到可靠的答案。

第一个组件定义了一个全局javascript变量,该变量可能与其他变量(可能存在的第三方组件或脚本)冲突。如果另一个组件或脚本也定义了此变量,则会出现运行时错误。如果这是整个应用程序(包括您使用的任何其他组件)中的唯一实例,那么它就不会有问题。尽管如此,不定义全局变量还是比较简单。

在构造函数中意味着对于组件的每个实例,您也将拥有该变量的一个实例。我认为您最好按照第一个示例使用它,因为无论组件的实例有多少,它都只会创建一个变量。但也值得注意的是,如果您采用这种方法,并且您的程序运行了一年多,那么在某些情况下可能是不正确的

首先让我们回答以下问题。通过回答,我们做出正确的选择。 currYear变量是否会被应用程序以外的其他组件使用?如果否,则应在应用程序组件内部实现。 为什么你会问: 1.其他开发人员的代码可读性。 2.为了明确currYear仅由应用程序组件使用,不使用任何其他组件 组成部分。 3.防止意外变化。

在第一种情况下:

const currYear = Date.now().getFullYear(); // Date is created here

class App extends React.Component {
  render() {
    return <MyComponent year={currYear} />;
  }
};
const curryyear=Date.now().getFullYear();//日期在此处创建
类应用程序扩展了React.Component{
render(){
返回;
}
};
currYear是从其他文件中需要该文件或包含在第页中的日期。 在第二个示例中,您在创建类实例时声明currYear,因此日期将不同:

class App extends React.Component {
  constructor() {
    super();
    this.currYear = Date.now().getFullYear();
  }

  render() {
    return <MyComponent year={this.currYear} />;
  }
};

<App/> // Date is created here
类应用程序扩展了React.Component{
构造函数(){
超级();
this.currYear=Date.now().getFullYear();
}
render(){
返回;
}
};
//日期在此处创建

此外,第一种模式在几乎所有情况下都非常糟糕,例如,如果您使用currYear.setDate(…)变量值将在每个类中更改,而不重新呈现视图。

在这种特殊情况下,它们是等效的,主要是因为
应用程序
应该实例化一次

对于多次实例化的组件来说,情况并非如此。如果用户更改了系统时间或新年到来,
this.curryyear
也会在将来的组件实例中更改

使用常量作为类字段提供了更大的灵活性。在测试期间可能需要更改它们,这可能会提高可测试性。并且可以在需要时在子类中更改。即使您没有将类设计为可扩展的,其他开发人员也可能从可扩展性中获益:

class BackToTheFutureApp extends App {
  currYear = 1955;
}

在第一种情况下,
curryyear
将在解释代码时进行评估。在第二种情况下,
curryyear
将不会被计算,除非应用程序的某个部分执行
new app()
,因此,它们不是完全等价的。例如,假设在新年前几毫秒解释代码,然后调用
new App()
,生成不同的日期!我个人会选择第二种方法虽然我同意使用实例变量“看起来”更干净、更安全,但我看不到第一个示例会出现问题的实际场景,因为我们正在使用React(js模块、封装等)。你怎么会认为它定义了一个全局变量?如果此代码在全局范围内进行评估,
App
也将是全局范围。幸运的是,它们不是并且可能有模块作用域。我只为每个文件编写一个组件。因此,我不认为任何人会对它的使用地点感到困惑。我也不认为这两种方法比另一种更具可读性,也不认为更容易出错。谢谢你的回答。你的最后一句话是没有意义的,因为我们假设变量永远不会改变。。。曾经此外,在第二个示例中执行
setDate()
也不会重新渲染任何内容。@Chris在第二个示例中,您可以将其置于状态并调用setState,但在第一个示例中,您不能执行该操作。@Chris最重要的一点是,在第二个示例中,您可能会在每个创建的应用程序实例上获得不同的日期。我意识到,但是请考虑提供“原样”的例子。我们不考虑移动或更改任何东西。您知道在第二个示例中,您将获得不同的组件使用日期,对吗?如果是这样的话,并且如果您想使用静态currDate,请将其放置在组件类中,如
static currYear=Date.now().getFullYear()
Good answer。类字段
currYear=1955
在babel中传输到
this.currYear=1955
中,对吗?那么为什么它提供了更多的灵活性呢?除此之外,我的理解是,我的示例是等效的,除非同一组件被多次使用,在这种情况下,
this.currYear
会在每个新实例中重新设置,而第一个示例中的情况并非如此。对吗?对,没错。它提供了更大的灵活性,因为
this.currYear
可以在子类中设置为其他内容(甚至可以在
App
中通过一些黑客行为进行修补,例如用于测试),而
currYear
不能。使用
1955
而不是
currYear
常量将需要覆盖整个
renderclass BackToTheFutureApp extends App {
  currYear = 1955;
}