React.js中声明式和命令式之间的区别?

最近我一直在研究很多关于功能和使用Facebook JavaScript库React.js的方法。 当谈到与JavaScript世界的其他部分的差异时,经常会提到两种编程风格,即declarativeimperative

两者有什么区别?


声明式风格,就像反应一样,可以让你通过说“应该看起来像这样”来控制应用程序中的流程和状态。 势在必行的风格可以扭转这种局面,并允许您通过说“这就是您应该做的事”来控制您的应用程序。

声明的好处是你不会陷入表示状态的实现细节中。 您正在委派保持应用程序视图一致的组织组件,以便您只需担心状态。

想象一下,你有一个管家,这是一个框架的隐喻。 你想吃晚饭。 在一个紧迫的世界里,你会一步一步告诉他们如何做晚餐。 你必须提供这些说明:

Go to kitchen
Open fridge
Remove chicken from fridge
...
Bring food to table

在一个声明性的世界里,你会简单地描述你想要的

I want a dinner with chicken.

如果你的管家不知道如何制作鸡肉,那么你不能以声明风格进行操作。 就像骨干不知道如何改变自己去完成某项任务一样,你不能仅仅告诉它去完成这项任务。 例如,React可以是声明性的,因为它“知道如何制作鸡肉”。 相比骨干,只知道如何与厨房接口。

能够描述状态显着减少了bug的表面积,这是一个好处。 另一方面,由于您委托或抽象了实现状态的方式,您可能在事情发生方面缺乏灵活性。


设想一个简单的UI组件,比如“Like”按钮。 当你点击它时,如果它以前是灰色的,它将变成蓝色,如果它以前是蓝色,则变成灰色。

这样做的必要途径是:

if( user.likes() ) {
    if( hasBlue() ) {
        removeBlue();
        addGrey();
    } else {
        removeGrey();
        addBlue();
    }
}

基本上,你必须检查当前屏幕上的内容,并处理所有需要重新绘制当前状态的更改,包括撤销之前状态的更改。 你可以想象在真实世界的场景中这可能有多复杂。

相反,声明式方法将是:

if( this.state.liked ) {
    return <blueLike />;
} else {
    return <greyLike />;
}

由于声明式方法分离了关注点,因此这部分内容仅需处理UI在特定状态下的外观,因此更易于理解。


命令码:

当JavaScript代码被写入命令时,我们告诉JavaScript到底该做什么以及如何去做。 把它看作是我们正在给JavaScript命令准确地执行它应该采取的步骤。

例如,我给你谦卑的循环:

const people = ['Amanda', 'Geoff', 'Michael', 'Richard', 'Ryan', 'Tyler']
const excitedPeople = []

for (let i = 0; i < people.length; i++) {
  excitedPeople[i] = people[i] + '!'
}

不过,这是必要的代码。 我们正在命令JavaScript每一步都要做什么。 我们必须给它命令:

  • 为迭代器设置一个初始值 - (让i = 0)
  • 当它需要停止时告诉for循环 - (我<people.length)
  • 找到当前位置的人并添加一个感叹号 - (people [i] +'!')
  • 将数据存储在另一个数组中的第i个位置 - (excitedPeople [i])
  • 将i变量加1 - (i ++)
  • 声明代码:

    使用声明性代码,我们不会对所有步骤进行编码,以使我们获得最终结果。 相反,我们宣布我们想要完成的任务,并且JavaScript将负责完成它。 这个解释有点抽象,所以我们来看一个例子。 让我们来看看我们刚刚看到的循环代码的重要性,并将其重构为更具说明性。

    使用命令式代码,我们正在执行所有步骤以获得最终结果。 但是,我们真正想要的最终结果是什么? 那么,我们的出发点就是一连串的名字:

    const people = ['Amanda', 'Geoff', 'Michael', 'Richard', 'Ryan', 'Tyler']
    

    我们想要的最终目标是一个相同名称的数组,但每个名称都以感叹号结尾:

    ["Amanda!", "Geoff!", "Michael!", "Richard!", "Ryan!", "Tyler!"]
    

    为了让我们从起点到终点,我们只需使用JavaScript的.map()函数来声明我们想要完成的任务。

    const excitedPeople = people.map(name => name + '!')
    

    而已! 请注意,使用此代码我们没有:

    创建一个迭代器对象告诉代码何时应该停止运行使用迭代器访问people数组中存储每个新字符串的特定项目...所有这些步骤都由JavaScript的.map()数组处理方法。

    链接地址: http://www.djcxy.com/p/22875.html

    上一篇: Difference between declarative and imperative in React.js?

    下一篇: Difference between Declarative and Procedural Programming?