ES6的学习(一)

ES6的学习

字符串的扩展

  1. ES6 加强了对 Unicode 的支持,允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。
  2. 字符串的遍历器接口,ES6 为字符串添加了遍历器接口(详见《Iterator》一章),使得字符串可以被for…of循环遍历。
  3. 模板字符串

字符串的新增方法

  1. fromCodePoint 用于从 Unicode 码点返回对应字符,与fromCharCode的区别就是能不能识别码点大于0xFFFF的字符String.fromCodePoint方法有多个参数,则它们会被合并成一个字符串返回。
    String.fromCodePoint(0x20BB7)
    // "𠮷"
    
  • codePointAt方法会正确返回 32 位的 UTF-16 字符的码点
    let s = '𠮷a';
    s.codePointAt(0).toString(16) // "20bb7"
    s.codePointAt(2).toString(16) // "61"
    
  1. includes 返回布尔值,表示是否找到了参数字符串
  2. startsWith 返回布尔值,表示参数字符串是否在原字符串的头部。
  3. startsWith 返回布尔值,表示参数字符串是否在原字符串的尾部。
    let s = 'Hello world!';
    s.startsWith('Hello') // true
    s.endsWith('!') // true
    s.includes('o') // true
    
    let s = 'Hello world!';
    s.startsWith('world', 6) // true
    s.endsWith('Hello', 5) // true
    s.includes('Hello', 6) // false
    
    以上三个方法都可接收第二个参数使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束
  4. repeat方法返回一个新字符串,表示将原字符串重复n次。
    'x'.repeat(3) // "xxx"
    'hello'.repeat(2) // "hellohello"
    'na'.repeat(0) // ""
    
    //参数如果是小数,会被取整。
    'na'.repeat(2.9) // "nana"
    // 如果repeat的参数是负数或者Infinity,会报错。
    // 如果参数是 0 到-1 之间的小数,则等同于 0,
    // 参数NaN等同于 0。
    // 如果repeat的参数是字符串,则会先转换成数字。
    
  5. padStart 字符串补全长度,用于头部补全
    'x'.padStart(5, 'ab') // 'ababx'
    'x'.padStart(4, 'ab') // 'abax'
    
  6. padEnd 用于尾部补全
    'x'.padEnd(5, 'ab') // 'xabab'
    'x'.padEnd(4, 'ab') // 'xaba'
    
    padStart()和padEnd()一共接受两个参数,第一个参数是字符串补全生效的最大长度,第二个参数是用来补全的字符串。如果原字符串的长度,等于或大于最大长度,则字符串补全不生效,返回原字符串如果省略第二个参数,默认使用空格补全长度
  7. trimStart 消除字符串头部的空格,返回的都是新字符串,不会修改原始字符串。
  8. trimEnd 消除尾部的空格,返回的都是新字符串,不会修改原始字符串。
    const s = '  abc  ';
    s.trim() // "abc"
    s.trimStart() // "abc  "
    s.trimEnd() // "  abc"
    
  9. matchAll 方法返回一个正则表达式在当前字符串的所有匹配,详见《正则的扩展》的一章。
  10. replaceAll 历史上,字符串的实例方法replace()只能替换第一个匹配,如果要使用replace替换所有字符,就要使用正则表表达式。但是使用replaceAll可以一次性替换所有匹配。返回一个新字符串,不会改变原字符串
        'aabbcc'.replace(/b/g, '_') // 使用replace替换所有字符
       'aabbcc'.replaceAll('b', '_')  // 使用replaceAll方法,一次性替换所有匹配
    
  11. at 方法接受一个整数作为参数,返回参数指定位置的字符,支持负索引(即倒数的位置)
    const str = 'hello';
    str.at(1) // "e"
    str.at(-1) // "o"
    

正则的扩展(暂无研究)

数值的扩展

  1. 二进制和八进制表示法
  2. 数值分隔符ES2021,允许 JavaScript 的数值使用下划线(_)作为分隔符。
    123_00 === 12_300 // true
    
    12345_00 === 123_4500 // true
    12345_00 === 1_234_500 // true
    
  3. Number.isFinite 用来检查一个数值是否为有限的(finite)如果参数类型不是数值,Number.isFinite一律返回false。
    Number.isFinite(15); // true
    Number.isFinite(0.8); // true
    Number.isFinite(NaN); // false
    Number.isFinite(Infinity); // false
    Number.isFinite(-Infinity); // false
    Number.isFinite('foo'); // false
    Number.isFinite('15'); // false
    Number.isFinite(true); // false
    
  4. Number.isNaN 用来检查一个值是否为NaN。如果参数类型不是NaN,Number.isNaN一律返回false。
    Number.isNaN(NaN) // true
    Number.isNaN(15) // false
    Number.isNaN('15') // false
    Number.isNaN(true) // false
    Number.isNaN(9/NaN) // true
    Number.isNaN('true' / 0) // true
    Number.isNaN('true' / 'true') // true
    
  5. Number.parseInt ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。
  6. Number.parseFloat
  7. Number.isInteger 用来判断一个数值是否为整数。
  8. Number.EPSILON 新增一个极小的常量Number.EPSILON。根据规格,它表示 1 与大于 1 的最小浮点数之间的差。
  9. Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限(整数范围在-2^53 到 2^53之间)。
    10.Number.isSafeInteger 判断整数是否在上面那两个常量之间

Math对象的扩展

  1. Math.trunc方法用于去除一个数的小数部分,返回整数部分。
  2. Math.sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值
    它会返回五种值。
    Math.sign(-5) // -1 参数为负数,返回-1;
    Math.sign(5) // +1 参数为正数,返回+1;
    Math.sign(0) // +0 参数为 0,返回0;
    Math.sign(-0) // -0 参数为-0,返回-0;
    Math.sign(NaN) // NaN 其他值,返回NaN。
    
  3. Math.cbrt()方法用于计算一个数的立方根
    还有其他不常用的Math函数,具体看ECMAScript 6 入门-数值的扩展

BigInt (大整数)数据类型

JavaScript 所有数字都保存成 64 位浮点数,这给数值的表示带来了两大限制。一是数值的精度只能到 53 个二进制位(相当于 16 个十进制位),大于这个范围的整数,JavaScript 是无法精确表示,这使得 JavaScript 不适合进行科学和金融方面的精确计算。二是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity。

函数的扩展(简单了解一下)

  1. 函数参数的默认值
  2. rest 参数
  3. 严格模式
  4. name 属性
  5. 箭头函数

数组的扩展

  1. 扩展运算符...它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列
    • 用法
      console.log(...[1, 2, 3])
      // 1,2,3
      
    • 用法 复制数组
      const a1 = [1, 2];
      // 写法一
      const a2 = [...a1];
      // 写法二
      const [...a2] = a1;
      
    • 用法三 合并数组
      const arr1 = ['a', 'b'];
      const arr2 = ['c'];
      const arr3 = ['d', 'e'];
      
      // ES5 的合并数组
      arr1.concat(arr2, arr3);
      // [ 'a', 'b', 'c', 'd', 'e' ]
      
      // ES6 的合并数组
      [...arr1, ...arr2, ...arr3]
      // [ 'a', 'b', 'c', 'd', 'e' ]
      
    • 任何定义了遍历器(Iterator)接口的对象(参阅 Iterator 一章),都可以用扩展运算符转为真正的数组(Set, Map , Generator )
  2. Array.from(),将两类对象转为真正的数据:类数组,以及可遍历对象(包括Map以及Set数据类型)
    let arrayLike = {
        '0': 'a',
        '1': 'b',
        '2': 'c',
        length: 3
    };
    
    // ES5的写法
    var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
    
    // ES6的写法
    let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
    
  3. Array.of() 将一组值,转换为数组
    Array.of() // []
    Array.of(undefined) // [undefined]
    Array.of(1) // [1]
    Array.of(1, 2) // [1, 2]
    
  4. copyWithin数组的实例方法 ,当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组
    Array.prototype.copyWithin(target, start = 0, end = this.length)
    target(必需):从该位置开始替换数据。如果为负值,表示倒数。
    start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
    end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。
    [1, 2, 3, 4, 5].copyWithin(0, 3) // 将该数组的从索引3开始的数据到最后的数据,复制到索引0开始的位置
    
  5. find 找出第一个符合条件的数组成员,参数是一个函数。返回符合这个函数的第一个成员,没有的话返回undefined
    [1, 4, -5, 10].find((n) => n < 0)
    
  6. findIndex 与上一个方法类似,不过返回值是找到的成员的索引,如果没有的话就返回-1
    [1, 5, 10, 15].findIndex(function(value, index, arr) {
      return value > 9;
    }) // 2
    
  7. fill使用给定值,填充一个数组
    new Array.fill('填充的数据','开始位置','结束位置')
    ['a', 'b', 'c'].fill(7) //  [7, 7, 7]
    ['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']
    // 如果开始位置,结束位置都没有的话 就从开始到结束
    // 如果开始位置有,结束位置没有的话也是从开始到结束
    
  8. entries(),keys() 和 values()
    for (let index of ['a', 'b'].keys()) {
      console.log(index);
    }
    // 0
    // 1
    
    for (let elem of ['a', 'b'].values()) {
      console.log(elem);
    }
    // 'a'
    // 'b'
    
    for (let [index, elem] of ['a', 'b'].entries()) {
      console.log(index, elem);
    }
    // 0 "a"
    // 1 "b"
    // 如果不使用for...of循环,可以手动调用遍历器对象的next方法,进行遍历。
    let letter = ['a', 'b', 'c'];
    let entries = letter.entries();
    console.log(entries.next().value); // [0, 'a']
    console.log(entries.next().value); // [1, 'b']
    console.log(entries.next().value); // [2, 'c']
    
  9. includes 表示数组中是否包含给定的值,与字符串中的includes相似,返回值为true,false
    includes('查找的值','开始位置')
    // 该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。
    
  10. flat 将嵌套的数组“拉平 flatMap 方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法
    // flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。
    [1, 2, [3, [4, 5]]].flat()
    // [1, 2, 3, [4, 5]]
    
    [1, 2, [3, [4, 5]]].flat(2)
    // [1, 2, 3, 4, 5]
    
    // 相当于 [[2, 4], [3, 6], [4, 8]].flat()
    [2, 3, 4].flatMap((x) => [x, x * 2])
    // [2, 4, 3, 6, 4, 8]
    
  11. at 接受一个整数作为参数,返回对应位置的成员,支持负索引,参数超过范围的话默认返回值为undefined
    const arr = [5, 12, 8, 130, 44];
    arr.at(2) // 8
    arr.at(-2) // 130
    // 参数位置超出了数组范围,at()返回undefined。
    

对象的扩展

  1. ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
    const foo = 'bar';
    const baz = {foo};
    baz // {foo: "bar"}
    
    // 等同于
    const baz = {foo: foo};
    
  2. 对象中的属性名可以使用表达式
    let lastWord = 'last word';
    const a = {
      'first word': 'hello',
      [lastWord]: 'world'
    	};
    	
    	a['first word'] // "hello"
    	a[lastWord] // "world"
    	a['last word'] // "world"
    
  3. 方法的 name 属性 (方法的name属性返回函数名)
  4. super 关键字 我们知道,this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象。
  5. 对象的扩展运算符(与数组的扩展运算符一致,ES2018将这个运算符引入到了对象)

对象的新增方法

  1. Object.is 比较两个值是否相同,注意 -0 和 0 比较式不相同的
    Object.is(120,120) // true
    Object.is(NaN,NaN) // true
    
  2. Object.assign(target,source) 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
    • 如果只有一个参数,Object.assign()会直接返回该参数。const obj = {a: 1}; Object.assign(obj) === obj // true
    • 如果该参数不是对象,则会先转成对象,然后返回。typeof Object.assign(2) // "object"
    • 由于undefinednull无法转成对象,所以如果它们作为参数,就会报错。
    • Object.assign()拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。
    const target = { a: 1 };
    const source1 = { b: 2 };
    const source2 = { c: 3 };
    
    Object.assign(target, source1, source2);
    target // {a:1, b:2, c:3}
    Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。
    注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
    
  3. Object.getOwnPropertyDescriptors 返回指定对象所有自身属性(非继承属性)的描述对象。
    const obj = {
      foo: 123,
      get bar() { return 'abc' }
    };
    
    Object.getOwnPropertyDescriptors(obj)
    // { foo:
    //    { value: 123,
    //      writable: true,
    //      enumerable: true,
    //      configurable: true },
    //   bar:
    //    { get: [Function: get bar],
    //      set: undefined,
    //      enumerable: true,
    //      configurable: true } }
    
  4. Object.setPrototypeOf与 __proto__相同,用来设置一个对象的原型对象
    // 使用方式
    Object.setPrototypeOf(object, prototype)
    let proto = {};
    let obj = { x: 10 };
    Object.setPrototypeOf(obj, proto);
    
    proto.y = 20;
    proto.z = 40;
    
  5. Object.getPrototypeOf 该方法与Object.setPrototypeOf方法配套,用于读取一个对象的原型对象。
    Object.getPrototypeOf(obj);
    
  6. Object.keys(),返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
    var obj = { foo: 'bar', baz: 42 };
    Object.keys(obj)
    // ["foo", "baz"]
    
  7. Object.values(),方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值
    const obj = { foo: 'bar', baz: 42 };
    Object.values(obj)
    // ["bar", 42]
    
  8. Object.entries() 方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
    const obj = { foo: 'bar', baz: 42 };
    Object.entries(obj)
    // [ ["foo", "bar"], ["baz", 42] ]
    
  9. Object.fromEntriesObject.fromEntries()方法是Object.entries()的逆操作,用于将一个键值对数组转为对象。
    Object.fromEntries([
      ['foo', 'bar'],
      ['baz', 42]
    ])
    // { foo: "bar", baz: 42 }
    // 该方法的主要目的,是将键值对的数据结构还原为对象,因此特别适合将 Map 结构转为对象。
    // 例一
    const entries = new Map([
      ['foo', 'bar'],
      ['baz', 42]
    ]);
    
    Object.fromEntries(entries)
    // { foo: "bar", baz: 42 }
    
    // 例二
    const map = new Map().set('foo', true).set('bar', false);
    Object.fromEntries(map)
    // { foo: true, bar: false }
    

运算符的扩展

  1. ** 指数运算符
    2 ** 2 // 4
    2 ** 3 // 8
    
  2. 链判断运算符
    // 如果存在一个值,需要连续判断该值的上层是否存在。这种情况下可以使用链判断运算符
    const firstName = (message
      && message.body
      && message.body.user
      && message.body.user.firstName) || 'default';
    // 上面是正常情况下判断
    // 下面是链判断运算符
    const firstName = message?.body?.user?.firstName || 'default';
    //上面代码使用了?.运算符,直接在链式调用的时候判断,左侧的对象是否为null或undefined。如果是的,就不再往下运算,而是返回undefined。
    
  3. Null 判断运算符?? 读取对象属性的时候,如果某个属性的值是null或undefined,有时候需要为它们指定默认值。常见做法是通过||运算符指定默认值。
    const headerText = response.settings.headerText || 'Hello, world!';
    const animationDuration = response.settings.animationDuration || 300;
    const showSplashScreen = response.settings.showSplashScreen || true;
    	上面的三行代码都通过||运算符指定默认值,但是这样写是错的。开发者的原意是,只要属性的值为nullundefined,默认值就会生效,但是属性的值如果为空字符串或false0,默认值也会生效。
    为了避免这种情况,ES2020 引入了一个新的 Null 判断运算符??。它的行为类似||,但是只有运算符左侧的值为nullundefined时,才会返回右侧的值。
    const headerText = response.settings.headerText ?? 'Hello, world!';
    const animationDuration = response.settings.animationDuration ?? 300;
    const showSplashScreen = response.settings.showSplashScreen ?? true;
    // 上面代码中,默认值只有在左侧属性值为null或undefined时,才会生效。
    // 这个运算符的一个目的,就是跟链判断运算符?.配合使用,为null或undefined的值设置默认值。
    const animationDuration = response.settings?.animationDuration ?? 300;
    
  4. 逻辑赋值运算符
    // 或赋值运算符
    x ||= y
    // 等同于
    x || (x = y)
    
    // 与赋值运算符
    x &&= y
    // 等同于
    x && (x = y)
    
    // Null 赋值运算符
    x ??= y
    // 等同于
    x ?? (x = y)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值