字符串扩展

Unicode相关补充

引入"\u{xx}"来表示码点,之前只能表示\u0000-\uffff
引入String.fromCodePoint()能正确读取大于uFFFF的unicode编码
引入s.codePiointAt()用于读取大于0xFFFF的字符的unicode编码
例如let s = '?a'读取s的第一个字符

//繁琐,绕,不推荐
s.codePoint(0).toString(16); //20bb7
String.fromCodePoint(0x2bb7)  //?

或者

for (let i of s) {
  console.log(i);
}

或者

Array.from(s)[0]

下面两种都是利用字符串的可迭代;

es6补充的新方法:

includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部

这个查找应该多用正则匹配较多,而且功能更强大

  • 复制字符串

    引入了一个可copy字符串的功能s.repeat(n)返回新字符串,n会隐式转换Number(n)小于0或者等于Infinity会报错,等于NaN返回空串
    我觉得这样可能会更好:s.concat(s.repeat(n))这样不会返回空串

  • 补全字符串
    有两个方法s.padStart(num, s1)在头部补充s1字符串来达到num的长度
    注意:当s.length > num时直接返回s不补全了;当s.length + s1.length < num那么s1.repeat(n)直到>=,除去多余部分;当s.length + s1.length> num,直接加上s1去除多余部分;
    同理s.padEnd(num, s1);从尾部添加
  • 字符串中代入变量
    之前都是字符串拼接的方式实现变量与字符串的连接,

    let s = 123;
    "java"  + s + "script   //可以用这个`java${s}script`

    这样就很方便很强大

函数扩展

  • 引入了函数默认值的概念
    默认值是变量,变量必须先声明

    function f(x = 123) {
      console.log(x)
    }
    f();
    f(undefined);

    当实参为空或者undefined时才会采用默认值

  • 默认值与参数解构的结合

    function f1({x = 0, y = 0}) {
      console.log(x, y)
    }
    function f2({x, y} = {x:0, y:0}) {
      console.log(x, y)
    }
    function f3({x = 0, y = 0} = {x:0, y:0}) {
      console.log(x, y)
    }
    f1(); //报错
    f2(); //0 0 
    f3(); //0 0
    f1({}); //0 0
    f2({}); //undefined undefined
    f3({}); //0 0
    

    理解这三个形式:f1只对x,y设置了默认值,并没有对形参整体设置默认值;f2只对形参整体设置了默认值,并没有对x,y分别设置默认值;f3则都对x,y设置了默认值以及形参整体设置默认值

  • 拥有默认值时的length属性
    length会等于至少需要n个参数就能允许函数不报错;那么length === n

    (function (a = 0, b, c) {}).length // 0
    (function (a, b = 1, c) {}).length // 1
  • 拥有默认值后的作用域变化
    函数一旦有默认值,我认为函数体内部会生成子作用域被参数作用域包裹,形成完成的函数作用域;
  • rest参数
    就是利用...扩展功能倒过来取数组,其中包含了函数所有实参等价于Array.prototype.slice.apply(arguments, [n, m])

    function f(a, ...args) {
      console.log(args)
    }
    f("a", 1, 2, 3);

    注意rest参数必须放最后

  • 箭头函数,值得注意的是this的执行,如果函数用箭头函数书写,this指向决定于定义时;如果是普通function书写,那么this执行决定于执行时;

数组扩展

强大而又常用的数组来了

  • ...扩展运算符,用于将具有Iterator接口的对象分解成参数序列;强大而又小巧的功能
    注意只能分解一层

    let arr = [1, 2, [3, 4]]
    ...arr; // 1 2 [3, 4]

    应用有很多:数组合并[...[1, 2], 3];数组浅拷贝[...arr];rest参数应用;
    [...(new Array(2))]对于空位数组会将其转化为undefined

  • arr.flat(n)能解决分解一层的问题,返回新数组

    [[1, 2, [3, 4]]].flat(2);   //[1, 2, 3, 4]

    这是两层的,那么多层或不确定多层怎么办呢?用arr.flat(Infinity)统一解决
    [1,,3].flat()会跳过空格,输出[1, 3]

  • arr.flatMap()是只能分解一层,但是能传入函数,功能类似数组的map,将数组成员代入函数返回相应的值组合成新数组返回[2, 3, 4].flatMap((x) => [x, x * 2]); //[2, 4, 3, 6, 4, 8]

    而flat(),flatMap()对于空位跳过,并不保留

    [1,,3].flat();                           //[1,3]
    [1,,3].flatMap(elem => elem);            //[1,3]
  • Array.from();该方法会将类数组对象和可遍历对象,转化为数组;它应该是...扩展运算符的升级版,把不具备Interator接口的类数组对象也能处理为数组;
    Array.from(new Array(2))对于空位数组会将其转化为undefined
    并且Array.from() 也能接受第二个参数为函数,类似数组的map,经过函数处理后返回新数组

    var arr = [1, 2];
    var arr1 = Array.from(arr, (elem, index, arr) => elem * 2);
  • Array.of()用于弥补Array(3)的不足,这个结果是length为3的空位数组,而Array.of(3)则会生成一个length为1,元素为3的数组[3]
    可以用一个函数模拟:

    function arryOf() {
        return [].slice.apply(arguments)
    }
  • find()findIndex()都是查找是否有符合要求的成员,前者返回第一个满足条件的成员值;后者则返回该成员的索引值;

    var a = [1, 2, 3, 4].find((elem, index, arr) => elem > 3);   //4
    var aIndex = [1, 2, 3, 4].findIndex((elem, index, arr) => elem > 3);   //3

    当查找对象为NaN时,NaN与NaN之间判断会返回true,也就是会满足要求
    find()和findIndex()会将空位处理成undefined。

    // find()
    [,'a'].find(x => true) // undefined
    // findIndex()
    [,'a'].findIndex(x => true) // 0
  • 与find类似的还有一个arr.includes(elem, start)返回布尔值;[1, 2, NaN].includes(NaN); //true
  • fill(target, start, end)用来填充数组,索引从start开始到end(不包括end),的元素都替换为target;(new Array(3).fill(undefined))会改变原数组并返回
  • Array.prototype.copyWithin(target, start = 0, end = this.length)(不包括end);该方法作用是将索引值为[start, end)的元素,去替换从索引值[target,target+end-start]的元素,整合的后的数组,长度超过原长度则去除多余部分,,改变原数组并返回

    var arr = [1,1,3,3,4];
    arr.copyWithin(2,0,5);   // [1, 1, 1, 1, 3]
    arr.copyWithin(4,0,5);   // [1, 1, 3, 3, 1]

数组中关于空位的处理

ES5 对空位的处理,已经很不一致了,大多数情况下会忽略空位。
forEach(), filter(), reduce(), every() 和some()都会跳过空位。
map()会跳过空位,但会保留这个值
join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串
// map方法
[,'a'].map(x => 1) // [,1]
// join方法
[,'a',undefined,null].join('#') // "#a##"
// toString方法
[,'a',undefined,null].toString() // ",a,,"

ES6大部分处理为undefined,例如:Array.from(),(...arr),entries()、keys()、values()、find()和findIndex()
for-of对于空数组遍历会输出undefined

let arr = new Array(3);   
for(let i of arr) {
  console.log(i);    
}                //undefined undefined undefined

应该至少是与迭代器相关的方法都会输出undefined;而fill()copyWithin()方法按空位正常处理,[,'a','b',,].copyWithin(2,0) // [,"a",,"a"]


Infinity
293 声望9 粉丝

学前端中,只想激情优雅的写代码