程序设计的基本元素

  1. 基本表达式,用于表示语言关心的最简单个体。
  2. 组合的方法,通过它们可以从简单的东西出发构造出符合的元素。
  3. 抽象的方法,通过它们可以为复合对象命名,并将它们当做单元去操作。

在程序设计中,我们需要处理两类要素:过程和数据。数据是一种我们希望去操作的“东西”,而过程就是有关操作这些数据的规则的描述。

抽象过程

数据参数化

如果我们要计算2的平方,你可能会这样写:

1
result = 2*2

现在我们要表达一个”平方”的概念,则有如下公式:

1
2
3
4
function square(x) {
return x * x;
}
result = square(2);

我们提出了一个复合过程平方,从只能计算2的平方到任意数的平方,差别在于给了过程一个参数,把数据参数化,可以提高抽象性和适用性,下面用平方去定义平方和的概念;

1
2
3
function squareSum(x, y) {
return square(x) + square(y);
}

实例:比如在canvas上绘制多个矩形:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const array = [
[1, 0],
[2, 0],
[3, 0]
]
function createRectangle(rectangleX, rectangleY, width, height) {
let rectangle = new Graphics();
rectangle.lineStyle(2, 0xff3300, 1);
rectangle.drawRect(0, 0, width, height);
rectangle.endFill();
rectangle.x = rectangleX;
rectangle.y = rectangleY;
}
function createRectangleFormArray(array, width, height) {
arr.forEach(arr => {
createRectangle(arr[0], arr[1], width, height);
})
}
createRectangleFormArray(array, 1, 1);

函数参数化

由上面可知,函数是对过程的简化,现在我们尝试把一个函数作为一个参数,那么会得到一个高阶函数

1
2
3
4
5
6
7
8
9
10
11
function sayHello(message) {
console.log("hello" + message)
}
function sayHi(message) {
console.log("Hi" + message)
}
function saySomething( fn, message) {
return fn(message);
}
saySomething(sayHello, world);
saySomething(sayHi, world);

实例:高阶组件的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { useState } from 'react';
function count() {
const [count] = useState(0);
return (
<div>
<p>you click { count } times</p>
</div>
)
}
//传入一个组件
function addNewProp(component, newProp, initValue) {
return function newComponent(){
const [newProp, setNewProp] = useState(initValue);
return (
const { ...others } = component.props;
<component newProp = { newProp } { ...others } ></component>
)
}
}
addNewProp(count, time, "2018")

抽象数据

现在我们要完成有理数的计算,就要有理数这个概念,下面构造有理数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function gcd(num1, num2){
return num2 === 0 ? num1 : gcd(num2, num1 % num2);
}
function makeRat(numer, denom) {
//化约,numer 分子,denom 分母
let gcd_number = gcd(numer, denom);
numer = numer / gcd_number;
denom = denom / gcd_number;
this.numer = numer;
this.denom = denom;
}
function addRat(x, y) {
let numer = x.numer * y.denom + y.numer * x.denom;
let denom = x.denom * y.denom;
return makeRat(numer, denom);
}
let x = new makeRat(1, 2);
let y = new makeRat(1, 2);

转换成class写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Rat{
construct(numer, denom) {
let gcd_number = gcd(numer, denom);
numer = numer / gcd_number;
denom = denom / gcd_number;
this.numer = numer;
this.denom = denom;
}
addRat(x, y) {
let numer = x.numer * y.denom + y.numer * x.denom;
let denom = x.denom * y.denom;
return new Rat(numer, denom);
}
}

现在我们可以轻松地完成对有理数的操作,从对整数的操作中释放出来,通过构造有理数这个概念,为整数提供了一份抽象,我们得以在有理数之上操作整数

实例:react Element的构造,封装真实DOM的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const ReactElement = function(type, key, ref, props) {
const element = {
type: type,
key: key,
ref: ref,
props: props,
};
return element;
};
export function createElement(type, config, children) {
//some code
return ReactElement(
type,
key,
ref,
props,
);
}
const component = () => (
<div>
<p>Are you sure?</p>
<Button color="blue">Cancel</Button>
</div>
)
const component = function buildComponent() {
return React.createElement(
"div",
null,
React.createElement(
"p",
null,
'Are you sure?'
),
React.createElement(
Button,
{ color: "blue" },
"Cancel"
)
)
}