mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 18:32:22 +00:00
docs(regex): 增加后行断言的介绍
This commit is contained in:
parent
1e8b21e22d
commit
342fe1da61
@ -312,7 +312,7 @@ Object.defineProperty(Object, 'is', {
|
|||||||
|
|
||||||
## Object.assign()
|
## Object.assign()
|
||||||
|
|
||||||
`Object.assign`方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target)。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。只要有一个参数不是对象,就会抛出TypeError错误。
|
`Object.assign`方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var target = { a: 1 };
|
var target = { a: 1 };
|
||||||
@ -324,6 +324,8 @@ Object.assign(target, source1, source2);
|
|||||||
target // {a:1, b:2, c:3}
|
target // {a:1, b:2, c:3}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`Object.assign`方法至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。只要有一个参数不是对象,就会抛出TypeError错误。
|
||||||
|
|
||||||
注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
|
注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -357,7 +359,19 @@ Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' })
|
|||||||
// { a: 'b', Symbol(c): 'd' }
|
// { a: 'b', Symbol(c): 'd' }
|
||||||
```
|
```
|
||||||
|
|
||||||
对于嵌套的对象,`Object.assign`的处理方法是替换,而不是添加。
|
`Object.assign`方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj1 = {a: {b: 1}};
|
||||||
|
var obj2 = Object.assign({}, obj1);
|
||||||
|
|
||||||
|
obj1.a.b = 2;
|
||||||
|
obj2.a.b // 2
|
||||||
|
```
|
||||||
|
|
||||||
|
上面代码中,源对象`obj1`的`a`属性的值是一个对象,`Object.assign`拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。
|
||||||
|
|
||||||
|
对于这种嵌套的对象,一旦遇到同名属性,`Object.assign`的处理方法是替换,而不是添加。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var target = { a: { b: 'c', d: 'e' } }
|
var target = { a: { b: 'c', d: 'e' } }
|
||||||
@ -366,7 +380,9 @@ Object.assign(target, source)
|
|||||||
// { a: { b: 'hello' } }
|
// { a: { b: 'hello' } }
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,`target`对象的`a`属性被`source`对象的`a`属性整个替换掉了,而不会得到`{ a: { b: 'hello', d: 'e' } }`的结果。这通常不是开发者想要的,需要特别小心。有一些函数库提供`Object.assign`的定制版本(比如Lodash的`_.defaultsDeep`方法),可以解决深拷贝的问题。
|
上面代码中,`target`对象的`a`属性被`source`对象的`a`属性整个替换掉了,而不会得到`{ a: { b: 'hello', d: 'e' } }`的结果。这通常不是开发者想要的,需要特别小心。
|
||||||
|
|
||||||
|
有一些函数库提供`Object.assign`的定制版本(比如Lodash的`_.defaultsDeep`方法),可以解决浅拷贝的问题,得到深拷贝的合并。
|
||||||
|
|
||||||
注意,`Object.assign`可以用来处理数组,但是会把数组视为对象。
|
注意,`Object.assign`可以用来处理数组,但是会把数组视为对象。
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
|
|
||||||
- Mathias Bynens, [Unicode-aware regular expressions in ES6](https://mathiasbynens.be/notes/es6-unicode-regex): 详细介绍正则表达式的u修饰符
|
- Mathias Bynens, [Unicode-aware regular expressions in ES6](https://mathiasbynens.be/notes/es6-unicode-regex): 详细介绍正则表达式的u修饰符
|
||||||
- Axel Rauschmayer, [New regular expression features in ECMAScript 6](http://www.2ality.com/2015/07/regexp-es6.html):ES6正则特性的详细介绍
|
- Axel Rauschmayer, [New regular expression features in ECMAScript 6](http://www.2ality.com/2015/07/regexp-es6.html):ES6正则特性的详细介绍
|
||||||
|
- Yang Guo, [RegExp lookbehind assertions](http://v8project.blogspot.jp/2016/02/regexp-lookbehind-assertions.html):介绍后行断言
|
||||||
|
|
||||||
## 数值
|
## 数值
|
||||||
|
|
||||||
|
@ -147,12 +147,12 @@ r1.exec(s) // ["aa"]
|
|||||||
r2.exec(s) // null
|
r2.exec(s) // null
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码有两个正则表达式,一个使用g修饰符,另一个使用y修饰符。这两个正则表达式各执行了两次,第一次执行的时候,两者行为相同,剩余字符串都是“_aa_a”。由于g修饰没有位置要求,所以第二次执行会返回结果,而y修饰符要求匹配必须从头部开始,所以返回null。
|
上面代码有两个正则表达式,一个使用`g`修饰符,另一个使用`y`修饰符。这两个正则表达式各执行了两次,第一次执行的时候,两者行为相同,剩余字符串都是`_aa_a`。由于g修饰没有位置要求,所以第二次执行会返回结果,而y修饰符要求匹配必须从头部开始,所以返回`null`。
|
||||||
|
|
||||||
如果改一下正则表达式,保证每次都能头部匹配,y修饰符就会返回结果了。
|
如果改一下正则表达式,保证每次都能头部匹配,`y`修饰符就会返回结果了。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var s = "aaa_aa_a";
|
var s = 'aaa_aa_a';
|
||||||
var r = /a+_/y;
|
var r = /a+_/y;
|
||||||
|
|
||||||
r.exec(s) // ["aaa_"]
|
r.exec(s) // ["aaa_"]
|
||||||
@ -346,3 +346,44 @@ escape('hi. how are you?')
|
|||||||
"hi\\. how are you\\?"
|
"hi\\. how are you\\?"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 后行断言
|
||||||
|
|
||||||
|
JavaScript语言的正则表达式,只支持先行断言(lookahead)和先行否定断言(negative lookahead),不支持后行断言(lookbehind)和后行否定断言(negative lookbehind)。
|
||||||
|
|
||||||
|
目前,有一个提案,在ES7加入后行断言。V8引擎4.9版已经支持,Chrome浏览器49版打开”experimental JavaScript features“开关(地址栏键入`about:flags`),就可以使用这项功能。
|
||||||
|
|
||||||
|
”先行断言“指的是,`x`只有在`y`前面才匹配,必须写成`/x(?=y)/`。比如,只匹配百分号之前的数字,要写成`/\d+(?=%)/`。”先行否定断言“指的是,`x`只有不在`y`前面才匹配,必须写成`x(?!y)`。比如,只匹配不在百分号之前的数字,要写成`/\d+(?!%)/`。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/\d+(?=%)/.exec("100% of US presidents have been male") // ["100"]
|
||||||
|
/\d+(?!%)/.exec("that’s all 44 of them") // ["44"]
|
||||||
|
```
|
||||||
|
|
||||||
|
上面两个字符串,如果互换正则表达式,就会匹配失败。另外,还可以看到,正则表达式的括号之中的部分,是不计入返回结果的。
|
||||||
|
|
||||||
|
”后行断言“正好与”先行断言“相反,`x`只有在`y`后面才匹配,必须写成`/(?<=y)x/`。比如,只匹配美元符号之后的数字,要写成`/(?<=\$)\d+/`。”后行否定断言“则与”先行否定断言“相反,`x`只有不在`y`后面才匹配,必须写成`/(?<!y)x/`。比如,只匹配不在美元符号后面的数字,要写成`/(?<!\$)\d+/`。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/(?<=\$)\d+/.exec("Benjamin Franklin is on the $100 bill") // ["100"]
|
||||||
|
/(?<!\$)\d+/.exec("it’s is worth about €90") // ["90"]
|
||||||
|
```
|
||||||
|
|
||||||
|
上面的例子中,正则表达式的括号之中的部分,也是不计入返回结果。
|
||||||
|
|
||||||
|
但是,如果括号之中还有括号,就会当作组匹配,返回匹配结果。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/h(?=(\w)+)/.exec("hodor") // ["h", "r"]
|
||||||
|
/(?<=(\w)+)r/.exec("hodor") // ["r", "h"]
|
||||||
|
```
|
||||||
|
|
||||||
|
上面代码中,第一个正则表达式是”先行断言“,只匹配后面跟着一个多个任意字符(`\w`)的`h`,这时符合条件的右边最后一个字符,会被括号之中的那个括号捕获返回,上例是`r`。第二个正则表达式是”后行断言“,只匹配前面是一个或多个任意字符(`\w`)的`r`,这时符合条件的左边第一个字符,会被括号之中的那个括号捕获返回,上例是`h`。
|
||||||
|
|
||||||
|
括号之中的那个括号捕获的部分,还可以用反斜杠引用。但是,”后行断言“的反斜杠引用,与通常的顺序相反,必须在对应的那个括号之前。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/(?<=(o)d\1)r/.exec("hodor") // null
|
||||||
|
/(?<=\1d(o))r/.exec("hodor") // ["r", "o"]
|
||||||
|
```
|
||||||
|
|
||||||
|
上面代码中,如果反斜杠引用(`\1`)在括号的后面,就不会得到匹配结果,必须放在前面才可以。
|
||||||
|
Loading…
x
Reference in New Issue
Block a user