博客

Redux:动作 Actions

动作(Actions)。在 Redux 的动作里会带着发送给 Store 的信息,动作是 Store 的唯一信息来源,可以使用 store.dispatch() 把动作发送给 Store。

下面就是一个动作,这个动作表示的是添加新的任务项目(假设这个动作来自一个任务列表应用):

const ADD_TODO = 'ADD_TODO'
{
  type: ADD_TODO,
  text: 'Build my first Redux app'
}

动作其实就是一个 JavaScript 对象,它里面必须得有个 type 属性,这个属性表示的是要执行的动作的类型,也就是在你的应用里会发生的一些事情。一般这个类型的值是一个字符串恒量,但这并不是必须的,你可以直接使用一个普通的字符串表示动作,但是对于大型应用来说,让动作的名字使用恒量是有好处的。在动作对象里,除了必须的 type 属性以外,你可以在这个对象里放任何东西。你可以参考 Flux Standard Action ,学习动作的结构。

第 13 周课程与内容简报

​学会自定义 Drupal 上的表格还有文本框的样式,了解 Drupal 的文件与图像。再看点关于函数式编程的东西。

JavaScript ES2015:模块 Module

你可以创建 JavaScript 模块,在模块里你可以导出需要导出的东西,然后在其它的地方,你可以导入模块提供的东西。

创建模块

创建一个模块,可以放在一个单独的 js 文件里,比如 talk.js:

let greeting = 'hello'

export { greeting }

现在,talk.js 就是一个模块,导出模块里的东西使用的是 export ,这里我们导出来变量 greeting 。

使用模块

使用模块就是导入模块提供的东西,创建一个 js 文件,名字是 index.js,在这个文件里:

import { greeting } from './talk'

console.log(greeting)

执行上面的代码,会在控制台上输出 “hello”,这个值是在 talk 模块里导出的 greeting 表示的东西。在 index.js 里,我们用 import 导入了 talk 模块里导出的 greeting 。

JavaScript ES2015(ES6):准备使用 ES2015

你写了几行 JavaScript 代码,放到浏览器上就能去运行,这是因为浏览器里面都有一个处理 JavaScript 语言的引擎。不同的浏览器使用的引擎可能不太一样,比如 Chrome 浏览器用的就是 Google 研究出来的 JavaScript 引擎。这套引擎不仅被放到了 Chrome 浏览器里,还可以被放在服务器上,也就是 Node.js。

因为处理 JavaScript 用的引擎不仅是只有 Google 的,还有其它的公司或者组织做的 JavaScript 引擎,这就需要大家坐在一起商量出一套规范。不然我们写的 JavaScript 代码,在不同环境下的运行结果可能就不一致了,我们可能要分别为 Chrome,IE,Firefox 各自去写一套 JavaScript 代码。对于我们开发者来说,谁都不喜欢这样。我们想要的是自己的 JavaScript 代码在任何支持运行 JavaScript 的环境下的运行结果都是一样的。

JavaScript Functional Programming:箭头函数 Arrow functions

箭头函数在 JavaScript 里面,是 ES6(ES2015)才加入进来的。因为函数里有个像箭头一样的符号:=>,所以叫箭头函数,英文经常也会称为 Fat arrow functions,胖乎乎的箭头函数。这种函数也称为 lambda 表达式。箭头函数不能当作构造函数使用。

语法

一个箭头函数看起来像这样:

const greet = () => hello

箭头(=>)左边是函数的参数,如果函数没有参数,要使用一组空白的括号,如果函数只有一个参数,这个参数的周围可以不用括号,如果有多少参数,这些参数要放在一组括号里,中间用逗号分隔开。

箭头右边是函数的主体部分,上面这个函数的主体只有一行,所以可以直接把主体放在箭头的右边,箭头函数会自动返回这种单行的主体的结果,也就是你不需要明确的使用 return 关键词返回值。如果函数的主体是多行的,可以把主体部分放在一组大括号里({  })。

单个参数

const greet = name => `hello, ${name}`

name 是 greet 这个箭头函数的一个参数,因为函数只有一个参数,所以它的周围不需要添加括号。

JavaScript Functional Programming:组合函数 Composition

组合(Composition)函数,就是把两个或以上的函数组合到一块儿,整成一个新的函数。我找到了一个很好的例子,很好地解释了组合函数这个概念。

比如一个应用主要是记录一下日常的花销(expenses),应用里的数据看起来像这样:

const expenses = [
  {
    name: '租金',
    price: 3000,
    type: '日常'
  }, 
  {
    name: '阿里云服务',
    price: 600,
    type: '服务'
  }, 
  {
    name: '健身中心',
    price: 50,
    type: '健康'
  }, 
  {
    name: '水电',
    price: 100,
    type: '日常'
  }
];

合计花销

现在我要合计一下所有花销,创建一个函数,用一下 map 与 reduce,这个函数像这样:

const sum = (source) => 
  source
    .map((item) => item.price)
    .reduce((accumulator, price) => accumulator + price, 0)

sum 这个函数接收一个 source 参数,在函数里,先用 map,返回 source 里的所有的 price(价格)。然后再用 reduce 去处理返回的 price ,这里就是合计所有的 price 的值。

这个函数用起来像这样:

let total = sum(expenses) // 结果:3750

JavaScript Functional Programming:不变性 Immutability

不变性(immutability),指的是一个东西被创建以后就不会发生变化了。函数式编程里的东西一般都具有这种特性。让对象具有不变性是一件好事,如果对象需要发生改变,你应该去创建一个新的对象,在新的对象里包含发生改变的部分,不要直接去修改对象本身。

下面这几个单词经常会出现:

  1. immutability:名词,不变性。表示东西不会发生改变的这种特性。
  2. immutable:形容词,不可变。可以说一个东西 immutable ,表示这个东西不会发生变化。
  3. mutability:名词,可变性,突变性,易变性。表示东西会发生改变的这种特性。
  4. mutate:动词,突变。
  5. mutable:形容词,可变。

在 JavaScript 里面,字符串与数字都具有不变性。也就是一个字符串一旦被创建,它的值就不会发生变化。但是 JavaScript 里的数组或对象是可变的,让它们不可变可以使用 Object.freeze 冻结一下它们(只能冻一层),也可以使用一些外部库,比如 Immutable.js。

实验一下:

let name = 'ninghao.net'
undefined

name[7]
"."

name[7] = '-'
"-"

name
"ninghao.net"

在上面尝试修改 name 的值(把 ninghao.net 里的点“ . ” 换成 “ - ” ),办不到。因为字符串这种值不能被改变。

JavaScript Functional Programming:Currying

Currying 指的就是把一个接受多个参数的函数,搞成每次只接收一个参数的函数序列。

看个例子:

const greet = (greeting, name) => {
  return `${greeting}, ${name}`
}

greet('hello', 'ninghao') // “hello, ninghao”

上面的 greet 就是一个接收多个参数的函数。如果把它转换成 Currying 风格的函数,会像这样:

const greet = greeting => name => `${greeting}, ${name}`

上面用了箭头函数,如果写成普通的函数应该像这样:

JavaScript Functional Programming:高阶函数 Higher order functions

高阶函数(higher-order functions),就是返回其它函数的函数,或者使用其它函数作为它的参数的函数。

使用函数作为参数

因为函数本身就是一个值,所以可以让函数作为参数传递给其它的函数。JavaScript 有些函数就需要用到函数类型的参数,比如 Array.map。

比如我有一组数据:

const names = ['小猫', '小狗', '小刺猬']

我要分别问候一下这组数据里的每个项目:

const greetings = names.map(function(name) {
  return `hi ~ ${name}`
})

console.log(greetings)
// ["hi ~ 小猫", "hi ~ 小狗", "hi ~ 小刺猬"]

上面的 map 方法里用了一个匿名函数作为它的参数。在这个函数里面,我们在数组里的每个项目的前面都加上了一个 “hi ~” ,map 会返回一个新的数组,这个数组我交给了 greetings 变量。

JavaScript Functional Programming:声明式与命令式

函数式编程属于声明式编程(declarative programming)的范畴,经常跟声明式编程一块儿讨论的是命令式编程(imperative programming),因为它们是两种不太一样的风格。

命令式编程一般就是说清楚具体要怎么样得到一个结果:先这样做,再这样做,然后再这样,如果这样,就这样做 ...  声明式编程就是声明(说明)一下你想得到的结果是什么样的:把这组电影里的平均分大于 9 分的电影过滤出来给我。

比如有一组电影,你想过滤出评分 9 分以上的电影。

let movies = [
  { title: 'The Shawshank Redemption', rating: 9.6 },
  { title: 'Forrest Gump', rating: 9.4 },
  { title: 'Roman Holiday', rating: 8.9 }
]


微信好友

用微信扫描二维码,
加我好友。



微信公众号

用微信扫描二维码,
订阅宁皓网公众号。



240746680

用 QQ 扫描二维码,
加入宁皓网 QQ 群。

统计

6997
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点