• ES6笔记


    顶层对象

    在浏览器环境指的是window对象, 浏览器和 Web Worker 里面,self也指向顶层对象, 但是 Node 没有self。 Node 里面,顶层对象是global,但其他环境都不支持。

    取顶层对象

    同一段代码为了能够在各种环境, 都能取到顶层对象, 现在一般是使用this变量,但是有局限性

    全局环境中,this会返回顶层对象。 但是,Node 模块和 ES6 模块中,this返回的是当前模块,严格模式下,这时this会返回undefined。 不管是严格模式,还是普通模式,new Function('return this')(),总是会返回全局对象。

    但是,如果浏览器用了 CSP(Content Security Policy,内容安全政策),那么eval、new Function这些方法都可能无法使用。 在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。

    // 方法一
    (typeof window !== 'undefined'
       ? window
       : (typeof process === 'object' &&
         typeof require === 'function' &&
         typeof global === 'object')
        ? global
        : this);
    ​
    // 方法二
    var getGlobal = function () {
      if (typeof self !== 'undefined') { return self; }
      if (typeof window !== 'undefined') { return window; }
      if (typeof global !== 'undefined') { return global; }
      throw new Error('unable to locate global object');
    };

    垫片库system.global模拟了这个提案,可以在所有环境拿到global。

    // CommonJS 的写法
    require('system.global/shim')();
    ​
    // ES6 模块的写法
    import shim from 'system.global/shim'; shim();
    上面代码可以保证各种环境里面,global对象都是存在的。
    ​
    // CommonJS 的写法
    var global = require('system.global')();
    ​
    // ES6 模块的写法
    import getGlobal from 'system.global';
    const global = getGlobal();

    let

    1.let 不能预解析 ( 只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。)

    2.同作用域内 let声明的变量 不允许重复

    3.有块级作用域{ ... } 内部定义变量 外部不能访问

    4.只能先声明在使用

     

    const

    let 4条规则都适用

    声明的常量不允许重新赋值 

    2.常量必须初始化

    const a; //报错 
    
    const a ={ } 

    3.可以改变引用类

    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。 const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。

    数组解构赋值

    let [a, b, c] = [1, 2, 3];
    //上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。
    ​
    let [foo, [[bar], baz]] = [1, [[2], 3]];
    foo // 1
    bar // 2
    baz // 3
    ​
    let [ , , third] = ["foo", "bar", "baz"];
    third // "baz"
    ​
    let [x, , y] = [1, 2, 3];
    x // 1
    y // 3
    ​
    let [head, ...tail] = [1, 2, 3, 4];
    head // 1
    tail // [2, 3, 4]
    ​
    let [x, y, ...z] = ['a'];
    x // "a"
    y // undefined
    z // []
    ​
    let [x = 1] = [undefined];
    x // 1
    ​
    let [x = 1] = [null];
    x // null

    上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

    对象解构赋值

    let {foo:aa,bar="hi"} = { foo:"123"}
    console.log(foo)//报错
    console.log(aa)123
    console.log(bar )//hi

    foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo

    如果p也要作为变量赋值,可以写成下面这样。

    let obj = {
      p: [
        'Hello',
        { y: 'World' }
      ]
    };
    ​
    let { p, p: [x, { y }] } = obj;
    x // "Hello"
    y // "World"
    p // ["Hello", {y: "World"}]

    字符串扩展

    查找字符
    let str = 'Hello Brother!';
    
    //includes 是否包含参数字符串
    str.includes('Br'); //true
    
    //startsWith  开头是否存在参数字符串
    str.startsWith('Hello') //true
    
    //endsWith 结尾是否存在参数字符串
    str.endsWith('er!')//true
    重复字符
    re.repeat(2); //"Hello Brother!Hello Brother!"
    
    re.repeat(-2); // Invalid count value
    re.repeat(Infinity); // Invalid count value
    //小数会取整 
    re.repeat(1.9) // "Hello Brother!"
    re.repeat(-0.9) // ""
    补全字符
    //补全开头 padStart 补齐尾部 padEnd
    let pd = 'Brother!'; 
    pd.padStart(14,'Hello '); //"Hello Brother!"
    //第一个参数为补齐的最大长度(整串字符) 第二个参数为补齐缺省的字符串
    
    //如果原始字符长度大于等于最大长度,返回原字符串
    pd.padStart(7,'Hello ')// 'Brother!'
    pd.padStart(8,'Hello ')// 'Brother!'
    
    //如果最大长度小于补齐长度,则去除超出部分
    pd.padStart(9,'Aay ')//'ABrother!'
    
    //如果缺省第二个参数则 默认使用空格补齐
    pd.padStart(9)//' Brother!'
    转义符
    //以 x 开头,会被当做 16 进制
    
     `x23` // #
    
     //以 u 开头,会被当做 unicode  字符
     `u004F` //"O"
    
    //如果无法编译将会报错
    ES2018 放松了对`标签模板`里面的字符串转义的限制,无法转义的返回`undefined`;

    模板字符串

    let obj={
      name:"ww",
      age:"18"
       }
    ​
    let  tag = "<div><span>"+obj.name +"</span></div>";
    let  tpl= `<div><span>${obj.name}</span></div>` 
    // 反引号 左上角 ESC键下方
    ​
    let  fn= function (info){
        return info
        }
    let  tpl= `<div><span>${obj.name}</span></div><div><span>${obj.age}</span></div>
        <div>
        <span>${fn("你好")}</span>
        <span>${1+1}</span>
        </div>

    函数参数解构赋值

    一,

    function fn(param="ss",age=15){ console.log(param - age); } fn();//ss - 15 fn("nihao",18)//nihao - 18

    二,

     function fn({name ="ls", age}={}) { console.log(name - age);
    
    } fn();//ls - undefind

    fn("nihao",18)//nihao - 18

    三, rest 参数(... 剩余参数)

    > 使用形式 `...arg` 实数以数组的形势赋给变量
    > reset 参数后不能再有形参,否则报错
    function fn (a,...arg){
        return arg;
    }
    fn(0,2,3,4,5)//[2,3,4,5]
    
    function foo (a,...arg,b){
        return arg;
    }
    //ught SyntaxError: Rest parameter must be last formal parameter
    只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
    / 报错
    function f(a, b = a) {
      'use strict';
      // code
    }
    
    // 报错
    const foo = function ({a, b}) {
      'use strict';
      // code
    };
    
    // 报错
    const fn = (...a) => {
      'use strict';
      // code
    };
    
    const obj = {
      // 报错
      fn({a, b}) {
        'use strict';
        // code
      }
    };

    函数扩展

    形参指定默认值
    > 形参 不能再次使用 let 和 const 声明
    > 形参不能重名
    > 函数 length 不包含设置默认值和后面的形参个数
    > 使用 `...arg` 中的参数 length 也不包含
    const fn = (x, y = 'Owen') =>( console.log(x,y));
    fn(1) // 1 "Owen"
    
    //默认参数 惰性求值
    let x = 99;
    function foo(y = x + 1) {
      console.log(y);
    }
    foo() // 100
    x = 100;
    foo() // 101
    //调用一次计算一次
    事实上 每次调用函数,如果不传递参数, 形参默认传递 `undefined`
     // 默认参数最好定义再尾部,因为使用形参默认参数,那么那个位置的形参必传
    
    function f(x, y = 5, z, ...arg) {
      return [x, y, z];
    }
    
    f() // [undefined, 5, undefined]
    f(1) // [1, 5, undefined]
    f(1, ,2) // 报错
    f(1, undefined, 2) // [1, 5, 2]
    
    //length 不包含设置默认值 和后面的形参 的个数,
    f().length // 1
    作用域
    > 函数中的 变量无法访问  默认值
    > 函数中的形参名不能和默认名一样
    //函数变量无法访问默认值
    function f(y = x) {
      let x = 2;
      console.log(y);
    }
    
    f() // ReferenceError: x is not defined
    
    //函数中的形参名不能和默认名一样
    //参数x = x形成一个单独作用域。实际执行的是let x = x,由于暂时性死区的原因,这行代码会报错
    function f(x = x) {
      console.log(x);
    }
    f()//  x is not defined
    
    var x = 1;
    function foo(x, y = function() { x = 2; }) {
      var x = 3;
      y();
      console.log(x);
    }
    
    foo() // 3
    x // 1
    由于 var 声明的 x 和函数形参 x 不再同一个作用域 , 因此调用 y() x值不变;
    如果 去掉 var , 那么 x 就指向 形参 x ,调用 y() x = 2。
     
    箭头函数
    >使用 ` () => ` 定义函数
    注意:
    - this 指向函数定义时所绑定的普通函数,不会被(bind,call,apply)更改,也不会被调用时的上下文改变。
    let fn = () =>console.log(this);
    let obj = {name:"Owen"};
    
    fn.call(obj) //window
    
    fn.bind(obj)
    fn() //window
    
    fn.apply(obj)  //window
     
     
     //可以通过改变宿主环境来改变 this 指向
     
     function foo (){
     
    return () =>{ 
      console.log(this);
    
      return ()=> {console.log(this)};
      }
    }
    foo.call(obj)() //{name: "Owen"}
    foo.call(obj)()() //{name: "Owen"} {name: "Owen"}
    - 外层没有普通函数 ,严格模式和非严格模式下它的this都会指向window(全局对象)。

    - 不可以当作构造函数,也就是说,不可以使用new命令,没有`prototype`属性,不支持`new.target`,否则会抛出一个错误。
    - 参数和箭头之间不能换行
    - 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

    - 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
    //定义简单函数
    let fn = () => 'Owen';
    fn()// 'Owen'
    
    let foo = r => r;
    foo('Owen') // 'Owen'
    
    let f = (num1,num2) => num1 + num2;
    f(1,2)//3
    
    //如果返回一个对象需要小括号包裹,f否则会报错
    let f = (name,age) => ({name,age});
    f('Owen',18)//{name: "Owen", age: 18}
    
    
    //如果代码部分大于一条语句,那么需要 大括号包裹,使用return 返回值
    
    let fn1 = r => {
        let a = 1;
        console.log(a);
        return r + a;
    
    }

    不推荐使用场景

    var obj = {
      gender:"man",
      getSex: () =>  {console.log(this.gender)}
    }
    obj.getSex() //undefined
    //this -> global
     
  • 相关阅读:
    CentOS7 安装Docker最新稳定版
    C#采集解析log文件及CSV文件数据到DataTable
    RedHat/CentOS8使用Bash脚本查看Linux上的系统信息
    DataTable Select用法总结
    web开发
    minio 文件服务器
    在 Idea 中使用 Maven
    UGUI源码分析(零): 环境搭建
    高德地图的使用 vueamap+vue
    unity 模型 工作流
  • 原文地址:https://www.cnblogs.com/gaoguowen/p/9889916.html
Copyright © 2020-2023  润新知