安装
yarn add normalizr
cnpm install normalizr
api
- normailze
- denormalize
- schema
实例
import {normalize, schema} from 'normalizr';
componentDidMount() {
const date = {
id: 1,
name: 'wang',
subject:[
{
id:11,
name:'语文',
score: [
{
id:111,
'期中': '80'
},
{
id:112,
'期末': '90'
}
],
},
{
id: 12,
name: '数学',
score: [
{
id: 113,
'期中': '80'
},
{
id: 114,
'期末': '90'
}
],
}
],
};
const scoreSchema = new schema.Entity('score');
const newScore = [scoreSchema];
const subjectSchema = new schema.Entity('subject', {
score: newScore
});
const newSubject = [subjectSchema];
const dataSchema = {
subject: newSubject,
};
const newData = normalize(date, dataSchema)
console.log(newData)
}
score被提出来,到entity中了, result中的subject是个数组索引
denormalize
denormalize(input, schema, entities)
即是
denormalize(result, schema, entities) // 第一个参数是normalize后得到结果中的
result
import { denormalize, schema } from 'normalizr';
const user = new schema.Entity('users');
const mySchema = { users: [ user ] }
const entities = { users: { '1': { id: 1 }, '2': { id: 2 } } };
const denormalizedData = denormalize({ users: [ 1, 2 ] }, mySchema, entities);
结果:
{
users: [
{ id: 1 },
{ id: 2 }
]
}
强制转换
- Number()
- String()
- Boolean()
Number()
Number()函数可以将任意类型的值,转换成数值
两种情况,参数是原始类型的值,和参数是对象(符合类型的值)
- 原始类型的值
Number()
1. 数值转换后还是数值
Number(123) //123
2. 字符串如果可以解析为数值,则转换成数值
Number('123') //123
3. 字符串如果不可以被解析为数值,则返回 NaN ----------------------(重要)
Number('123abc') // NaN
4. 空字符串 会被转换成 0 --------------------------------------(重要)
Number('') // 0
5. 布尔值 true转换成1 false转化成0 --------------------------(重要)
Number(true) //1
Number(false) //0
6. undefined被转换成 NaN -------------------------------------(重要)
Number(undefined) // NaN
7. null被转换成0 ---------------------------------------------(重要)
Number(null) //0
总结:
被转换成0的有:null false 空字符串
被转换成NaN的有: undefined 和 不可以被转化成数值的字符串
- 对象
简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组。
- 参数是对象时,返回NaN
特例:单个值得数组 返回数组中的单个值得 数值类型
Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
String()
String(123) // "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"
- String方法的参数如果是对象,返回一个类型字符串;
- String方法的参数如果是数组,返回该数组的字符串形式。
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
自动类型转换
三种情况js会自动转换数据类型
- (1) 不同类型的数据相互运算
- (2) 对非布尔类型的数据求布尔值
- (3) 对非数值类型的值使用一元运算符
自动转化的规则
- 预期是什么类型的值,就调用该类型的转化函数。
- 某个位子,预期是个字符串,就调用String函数。
- 如果该位置,可以是字符串,也可以是数值,则默认转成数值。
注意:自动转化具有不确定性,不易排错,一般在预期为数值,字符串,布尔值的地方使用 Number,String,Boolean就行显式转换
自动转换为字符串
- 字符串的自动转换,主要发生在字符串的 ( 加法运算 ) 时。
- (字符串 + 非字符串 , 会将非字符串转换为字符串 )
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
自动转化为数值
除了( 加法运算符 )有可能将云算子转换成字符串,其他 ( 运算符 ) 都会把云算子转化成 数值
- 注意:null转为数值时为0,而undefined转为数值时为NaN。
- null 转为数值是 0
- undefined 转为数字是 NaN
2018/6/18复习 Date对象
- Date实例方法:有to,get,set三种类型
get类: 获取 Date 对象的日期和时间
set类: 设置 Date 对象的日期和时间
to 类: 从 Date对象返回一个字符串,表示指定的时间
getFullYear() 返回四位年份
getMonth() 返回月份 ( 0表示1月 。。。。)
getDate() 返回日期号数 ( 从1开始 )
getDay() 返回星期几
getHours() 返回小时数
getMinutes() 返回分钟数
getSeconds() 返回秒数
componentDidMount() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth();
const datex = date.getDate();
const day = date.getDay();
const hoursx = date.getHours();
const minutesx = date.getMinutes();
const secondsx = date.getSeconds();
console.log(year, month + 1, datex, day, hoursx, minutesx, secondsx)
}
// 2018 6 18 1 11 11 21
- 表达式
表达式是 一个为了得到返回值的计算。
凡是预期为值的地方,都可以使用表达式。
表达式一定会返回一个值。 - 语句
语句以分号结尾。
一个分号就表示语句的结束。
多个语句可以写在一行内。 - 变量
变量是对值的具名引用。
prop-types库
import React, { Component } from 'react';
import PropTypes from 'prop-types'; // 引入prop-types库
class newc extends Component {
static propTypes = { // 定义一个静态属性proptypes
name: PropTypes.string, // 加 static 关键词定义静态属性是新写法,以前是类型.静态属性名
}
render() {
return (
<div className="newc">
测试prop-types
<div>{this.props.name}</div>
</div>
);
}
}
export default newc;
RegExp对象 复习
正则表达式 ( regular expression )
regular : 是正规的,规则的意思
expression : 是表达的意思
(1) 新建正则表达式有两种方法
- 一种是使用字面量,以斜杠开始和结束 ------------------- 编译时新建
如: let regularExprssion = /abc/;
- 一种是使用 RegExp 构造函数 ------------------------------- 运行时新建
RegExp构造函数,可以接受第二个参数,表示修饰符
如: let regularExpression = new RegExp('abc');
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;
- 在实际运用中,多采用字面量方式新建正则表达式,效率更高,也更直观。效率高是因为字面量方式在编译阶段就会新建,而 RegExp构造函数方法在运行时才会新建。
(2) 实例属性
正则对象的实例属性分为两类:
- 一类是和修饰符相关,返回一个布尔值,表示对应的修饰符是否设置
RegExp.prototype.ignoreCase : 返回boolean,表示是否设置了 i 修饰符。 -- 忽视大小写
RegExp.prototype.global : 返回boolean,表示是否设置了 g 修饰符。 -- 全局模式
RegExp.prototype.multiline: 返回boolean,表示是否设置了 m 修饰符。 -- 多线
- 另一类是与修饰符无关的属性
RegExp.prototype.lastIndex:返回一个数值,表示下一次开始搜索的位置。
该属性可读写,但是只在进行连续搜索时有意义
RegExp.prototype.source:返回正则表达式的字符串形式(不包括反斜杠) !!!
该属性只读。
例子:
let regexp = /abc/igm;
const ignoreCase = regexp.ignoreCase;
const global = regexp.global;
const multiline = regexp.multiline;
const lastIndex = regexp.lastIndex; // 下一次开始搜索的位置。
const source = regexp.source; // 返回正则表达式的字符串形式,不包括反斜杠。 source属性
console.log(ignoreCase, global, multiline, lastIndex, source)
// true true true 0 "abc"
(3) 实例方法
(1) RegExp.prototype.test() ----- 返回布尔值,表示是否匹配
正则实例的test()方法,返回一个布尔值,表示当前模式是否匹配参数字符串
const one = /name/.test('my name is xxxxx') // test()方法:当前模式是否匹配参数字符串
console.log(one)
// true
带有 g 修饰符时,可以通过 lastIndex 属性, 指定开始搜索的位置
- lastIndex属性只对同一个正则表达式有效
const one = /name/g; --------- const one = new RegExp('name', 'g'); 相等
one.lastIndex = 4;
one.test('正则带有g修饰符时,可以用lastIndex属性指定开始搜索的位置,name is xxx');
// true
one.lastIndex = 400;
// false
如果正则模式是一个空字符串,则匹配所有字符串。
new RegExp('').test('abc')
// true
(2) RegExp.prototype.exec()
---------------------------- 返回数组,匹配成功的子字符串。
如果正则表达式包含圆括号(组匹配),返回的数组会包括多个成员,第一个成员是整个匹配成功的结果,后面的成员是圆括号匹配成功的组。
即第二个成员对应第一个括号,第三个成员对应第二个括号,以此类推。整个数组的length属性等于组匹配的数量再加1。
---------------------------- 没有匹配成功,返回null
正则实例对象的exec方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回null。
-------------------------------- exec方法的返回数组还包含以下两个属性:
- input:整个原字符串。
- index:整个模式匹配成功的开始位置(从0开始计数)。
const one = /x(y+)z(c)/i;
const result = one.exec('xyyzcccccc xyyyyyyyyyzc');
console.log(one.source, 'source')
console.log(result.input, '整个源字符串')
console.log(result,'result')
说明:
正则带括号,即组匹配时,exec()方法返回的数组,成员有多个,
第一个成员是整个正则的匹配,
第二个成员是第一个括号的匹配
第三个成员是第二个括号的匹配
........
exec()方法返回的数组中,还有两个属性
input :整个原字符串
index :整个模式匹配成功的开始位置
结果:
x(y+)z(c) source
xyyzcccccc xyyyyyyyyyzc 整个源字符串
["xyyzc", "yy", "c", index: 0, input: "xyyzcccccc xyyyyyyyyyzc"] "result"
-----------------------------------------------------------------------------------
const one = /x(y+)z(c)/ig; // 正则带有 g 修饰符
one.lastIndex = 10; // 指定开始搜索的位置,在带有 g 修饰符时
const result = one.exec('xyyzcccccc xyyyyyyyyyzc');
console.log(one.source, 'source')
console.log(result.input, '整个源字符串')
console.log(result,'result')
说明:
当正则带有 g 修饰符时,可以用 lastIndex 属性指定开始搜索的位置
结果:
x(y+)z(c) source
xyyzcccccc xyyyyyyyyyzc 整个源字符串
["xyyyyyyyyyzc", "yyyyyyyyy", "c", index: 11, input: "xyyzcccccc xyyyyyyyyyzc"] "result"
(3) 字符串的实例方法
(1) String.prototype.match()
匹配成功返回数组,匹配失败返回null
- 当正则带有 g 修饰符时,match() 方法会一次性返回所有匹配成功的结果。
- 设置正则表达式的lastIndex属性,对match方法无效
var s = 'abba';
var r = /a/g;
s.match(r) // ["a", "a"]
r.exec(s) // ["a"]
字符串的matc()方法 和 正则的exec() 方法的区别
在有 g 修饰符时
math()返回所有匹配成果的结果, exec() 只返回第一个匹配成功的子字符串
(2) String.prototype.search() 返回匹配的位置
(3) String.prototype.replace() 返回匹配的位置
- 它接受两个参数,第一个是正则表达式,表示搜索模式,第二个是替换的内容。
匹配规则
(1) 字面量字符
大部分字符在正则表达式中,就是字面的含义,比如/a/匹配a,/b/匹配b。如果在正则表达式之中,某个字符只表示它字面的含义(就像前面的a和b),那么它们就叫做“字面量字符”(literal characters)。
- 只表示字面的含义的字符,是字面量字符。 ---- literal characters
(2) 元字符
除了字面量字符以外,还有一部分字符有特殊含义,不代表字面的意思。它们叫做“元字符”(metacharacters)
- 特殊意义的字符,是元字符 ---- metacharacters
点字符 ( . )
- 点字符(.)匹配除回车(\r)、换行(\n) 、行分隔符(\u2028)和段分隔符(\u2029)以外的所有字符。
. 点字符 匹配除了 ( 回车\r ), ( 换行\n) , ( 行分隔符\u2028 ), ( 段分隔符\u2029 ) 以外的所有字符
/r 是 return 的意思
/n 是 new line 的意思
位置字符( ^ $ )
^ 表示字符串的开始位置
$ 表示字符串的结束位置
选择符 ( | )
多个选择符可以联合使用。
选择符会包括它前后的多个字符,比如/ab|cd/指的是匹配ab或者cd,而不是指匹配b或者c。
如果想修改这个行为,可以使用圆括号。
竖线符号(|)在正则表达式中表示“或关系”(OR),即cat|dog表示匹配cat或dog。
多个选择符可以联合使用。
// 匹配fred、barney、betty之中的一个 ----- 匹配其中一个就行
/fred|barney|betty/
----------------------------------------
/a( |\t)b/.test('a\tb') // true
a和b之间有一个空格或者一个制表符都能匹配成功。
转义符 ( \ ) ---------- 需要转义的有12个字符
正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。比如要匹配+,就要写成+
- 正则表达式中,需要加反斜杠转移的字符,一共有 12 个 !!!!!!! ( 12个 )
- 正则表达式中,需要反斜杠转义的,一共有12个字符:
^
、.
、[
、$
、(
、)
、|
、*
、+
、?
、{
和\\
。 - 需要特别注意的是,如果使用RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。
需要转义的字符 12 个
. ---- 点字符
^ $ ---- 位置字符
| ---- 选择符
?* + ---- 量词符
[ ---- 字符类符号, 左中括号
{ ---- 重复类符号, 左大括号
( ) ---- 分组符
\\ ---- 双反斜杠, 转义 \ 反斜杠本身
字符类
字符类(class)表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内,比如[xyz] 表示x、y、z之中任选一个匹配。
有两个字符在字符类中有特殊含义。
(1) 脱字符(^)
-
如果方括号内的第一个字符是[^],则表示除了字符类之中的字符,其他字符都可以匹
配 -
如果方括号内没有其他字符,即只有[^],就表示匹配一切字符,其中包括换行符。相比之下,点号作为元字符(.)是不包括换行符的。
-
注意,脱字符只有在字符类的第一个位置才有特殊含义,否则就是字面含义。(重要)
[^xyz] 表示除了x、y、z之外都可以匹配。
[^] 表示匹配一切字符,包括换行符
. 点字符 : 匹配除了 /r /n /u2028 /u2029 字符外的所有字符
var s = 'Please yes\nmake my day!';
s.match(/yes.*day/) // null
s.match(/yes[^]*day/) // [ 'yes\nmake my day']
(2) 连字符( - )
某些情况下,对于连续序列的字符,连字符(-)用来提供简写形式,表示字符的连续范围。
- 比如,[abc]可以写成[a-c],[0123456789]可以写成[0-9],同理[A-Z]表示26个大写字母。
[1-31]
[1-31],不代表1到31,只代表1到3。
- 不要过分使用连字符,设定一个很大的范围,否则很可能选中意料之外的字符
最典型的例子就是[A-z],表面上它是选中从大写的A到小写的z之间52个字母,但是由于在 ASCII 编码之中,大写字母与小写字母之间还有其他字符,结果就会出现意料之外的结果。
/[A-z]/.test('\\') // true
大写字母与小写字母之间还有其他字符
预定义模式
( \b ) ---------------------- boundry 边界
( \s ) ---------------------- space 空格,空白,间隙的意思
( \d ) ---------------------- digit 数字
\d 匹配0-9之间的任一数字,相当于[0-9]。
\D 匹配所有0-9以外的字符,相当于[^0-9]。
\w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]。
\W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]。
\s 匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]。
\S 匹配非空格的字符,相当于[^ \t\r\n\v\f]。
\b 匹配词的边界。
\B 匹配非词边界,即在词的内部。
注意:正则表达式遇到换行符(\n)就会停止匹配。
var html = "<b>Hello</b>\n<i>world!</i>";
/.*/.exec(html)[0]
// "<b>Hello</b>"
[\S\s]指代一切字符
[\D\d]指代一切字符
...
var html = "<b>Hello</b>\n<i>world!</i>";
/[\S\s]*/.exec(html)[0]
// "<b>Hello</b>\n<i>world!</i>"
重复类
模式的精确匹配次数,使用大括号({})表示。 ----------------------- 精确匹配次数
- {n}表示恰好重复n次,
- {n,}表示至少重复n次,
- {n,m}表示重复不少于n次,不多于m次。
量词符
量词符用来设定某个模式出现的次数。
? 问号表示某个模式出现0次或1次,等同于{0, 1}。
* 星号表示某个模式出现0次或多次,等同于{0,}。
+ 加号表示某个模式出现1次或多次,等同于{1,}。
贪婪模式
三个量词符,默认情况下都是最大可能匹配,即匹配直到下一个字符不满足匹配规则为止。这被称为贪婪模式。
- 三个量词符? * +,默认是贪婪模式
- 如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。( 重要 )
*?:表示某个模式出现0次或多次,匹配时采用非贪婪模式。
+?:表示某个模式出现1次或多次,匹配时采用非贪婪模式。
var s = 'aaa';
s.match(/a+?/) // ["a"]
修饰符
修饰符(modifier)表示模式的附加规则,放在正则模式的最尾部。
(1) g 修饰符
默认情况下,第一次匹配成功后,正则对象就停止向下匹配了。g修饰符表示全局匹配(global),加上它以后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。
var regex = /b/;
var str = 'abba';
regex.test(str); // true
regex.test(str); // true
regex.test(str); // true
上面代码中,正则模式不含g修饰符,每次都是从字符串头部开始匹配。所以,连续做了三次匹配,都返回true。
--------------------------------
var regex = /b/g;
var str = 'abba';
regex.test(str); // true
regex.test(str); // true
regex.test(str); // false
上面代码中,正则模式含有g修饰符,每次都是从上一次匹配成功处,开始向后匹配。
因为字符串abba只有两个b,所以前两次匹配结果为true,第三次匹配结果为false。
(2) i 修饰符
默认情况下,正则对象区分字母的大小写,加上i修饰符以后表示忽略大小写(ignorecase)。
(3) m 修饰符 ---- 多行匹配,可以在位置符前后位置匹配 \n 换行符
m修饰符表示多行模式(multiline),会修改^
和$
的行为。默认情况下(即不加m修饰符时),^
和$
匹配字符串的开始处和结尾处,加上m修饰符以后,^
和$
还会匹配行首和行尾,即^和$会识别换行符(\n)。
/world$/.test('hello world\n') // false
/world$/m.test('hello world\n') // true
-----------------------------------------/m可以匹配换行符
var s = 'ab\n';
var r = /ab$/m;
console.log( r.test(s) ); //true
/^b/m.test('a\nb') // true
上面代码要求匹配行首的b,如果不加m修饰符,就相当于b只能处在字符串的开始处。
加上b修饰符以后,换行符\n也会被认为是一行的开始。
组匹配
正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。
- 注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。
var m = 'abcabc'.match(/(.)b(.)/);
m
// ['abc', 'a', 'c']
说明:
match正则内有括号时,返回的数组,第一个成员是全部的正则匹配,第二个成员是第一个括号的匹配,以此类推...
- 注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。
var m = 'abcabc'.match(/(.)b(.)/g);
m // ['abc', 'abc']
上面代码使用带g修饰符的正则表达式,结果match方法只捕获了匹配整个表达式的部分。
这时必须使用正则表达式的exec方法,配合循环,才能读到每一轮匹配的组捕获。
网友评论