• ES6学习笔记(持续更新中)


    生活还要继续代码撸起来

    一、关于定义变量  let和const

       //一、let
    //1. let 只在let命令所在的代码块内有效
    for (let i = 0;i < 5;i++){
    var a = i;
    let b = i;
    }
    console.log(a);
    //console.log(b);
    // 抛出错误 b is not defined

    //for 循环中的计数器,很适合使用let
    var arr = [];
    for(var i = 0; i < 10; i++){
    arr[i] = function(){
    console.log(i);
    }
    }
    arr[5](); // 输出 10

    let arr1 = [];
    for(let i = 0; i < 10; i++){
    arr1[i] = function(){
    console.log(i);
    }
    }
    arr1[5](); // 输出5

    // 2、不存在变量提升
    function test(){
    console.log(t1); // undefined
    //console.log(t2); // 抛出错误 b is not defined
    var t1 = 0;
    let t2 = 1;
    }
    test();
    // 3、暂时性死区
    /*
    * es6明确规定,如果区域块中存在let和const命令,这个区块对这些命令声明的变量,
    * 从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
    * 称为“暂时性死区”
    * */
    var tmp = 123;
    if(true){
    // tmp = 'abc' //tmp is not defined
    let tmp
    }
    // 4、不允许重复声明变量
    /*
    * let不允许在相同作用域内,重复声明同一个变量
    * */

    //二、块级作用域
    /*
    * 为什么需要块级作用域
    * 1、内层变量可能会覆盖外层变量
    * 2、用来计数的循环变量泄露为全局变量
    * */
    for(var k =0; k < 5; k++){}
    console.log(k);
    // 块级作用域的出现,实际上使得广泛应用的立即执行函数表达式(IIFE)不再必要了

    console.log(this)

    // 三、const 常量
    // const声明一个只读的常量。一旦声明,常量的值就不能改变。
    // const实际上保证的,并不是变量的值不得变动,而是变量指向
    // 的那个内存地址所保存的数据不得变动。对于简单类型的数据
    // (数值、字符串、布尔值),值就保存在变量指向的那个内存地址,
    // 因此等同于常量。但对于复合类型的数据(主要是对象和数组)
    // ,变量指向的内存地址,保存的只是一个指向实际数据的指针,
    // const只能保证这个指针是固定(即总是指向另一个固定的地址)
    // ,至于它指向的数据节后是不是可变的,就完全不可能控制了
    // 。因此,将一个对象声明为常量必须非常小心。

    let 和const注意:

    (1) 不存在变量提升,变量在声明之前使用报错;

    (2)同一个作用域里,不能重复定义变量;

    (3)let 只在let命令所在的代码块(块作用域)内有效;es6明确规定,如果区域块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。称为“暂时性死区”;

     

    二、解构赋值

     // 一、数组的解构赋值
    //基本用法
    /*
    * 从数组和对象中提取值,对变量进行赋值,这被称为解构
    * 可以从数组中提取值,按照对应位置,对变量赋值
    * 如果解构不成功,变量的值就等于undefined
    * */
    let [a,b,c] = [1,2,3];
    // a = 1 b = 2 c = 3
    let [i, k] = [1];
    // i = 1 k undefined
    let [x, y, ...z] = [1,2,3,4];
    // x = 1 y = 2 z = [3,4];
    let [q,...w] = [1];
    // q = 1 w = []
    /*
    * 默认值
    * 解构赋值允许指定默认值 ==> 例1
    * 只有当以个数组成员严格等于undefined,默认值才会生效 ==> 例2
    * 如果默认值是一个表达式,那么这个表达式是惰性求值的,即使只有在用到手的时候,才会求值。 ==> 例3
    * 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。==> 例4
    * */
    // 例1
    let [name , age = 18 ]= ['zsh'];
    //name = zsh age = 18
    // 例2
    let [name1 ,age1 = 18] = ['zsh',null];
    //name1 = zsh age = null
    // 例3
    function f(){
    console.log(1)
    }
    let [o = f()] = [1]; //这种情况下f()不运行
    let [t = f()] = []; // 这种情况下f()才会运行
    // 例4
    let [xx = 1,yy = xx] = [];
    // xx = 1 yy= 1
    // let [x1 = y1,y1 = 1] = [];
    //抛出错误:ReferenceError:y is not defined
    // 因为x1用y1做默认值时,y1还没有声明

    // 二、对象的解构赋值
    /*
    * 对象的解构与数组的解构有一个重要的不同。
    * 数组的元素是按次序排列的,变量的取值由它的位置决定;
    * 而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
    * 如果解构失败,变量的值等于undefined
    * 嵌套赋值
    * 默认值 (同数组)
    * */
    let { foo,bar } = {foo:'aaa',bar:'bbb'};
    // foo = 'aaa' bar = 'bbb'
    // 以上写法,是下面形式的简写
    // let { foo:foo,bar:bar } = { foo:'aaa',bar:'bbb' };
    let {foo1} = {foo:'aaa'};
    // fool undefined
    // 如果变量名与属性名不一致,必须写成下面之这样
    let {foo2:baz} = {foo2 :'bbb'};
    // baz = 'bbb' foo2 undefined
    // 嵌套赋值例子
    let obj = {};
    let arr = [];
    ({foo:obj.prop,bar:arr[0]} = { foo:123,bar:2 });
    // obj = {prop: 123} arr = [2]
    // 如果要将一个已经声明的变量用于解构赋值,必须要小心
    /*
    * 错误写法
    * let x ;
    * { x } = { x : 1 };
    * syntaxError:syntax error
    * 因为javascript引擎会将{x}理解成一个代码块,从而发生语法错误。
    * 只有不将大括号写在行首,避免JavaScript将其解释为代码块,才能解决这个问题。
    * 正确写法:
    * let x;
    * ({x} = {x:1})
    * */

    // 三、字符串的解构赋值
    let [aa,bb,cc,dd,ee] = 'hello';
    // aa = h bb = e cc = l dd = l ee = o

    // 四、数值和布尔值的解构赋值
    /*
    * 解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
    * undefined和null无法转为对象
    * */
    // 五、函数参数的解构赋值
    /*
    * 通过对这个对象进行解构,得到变量x和y的值。如果解构失败,x和y等于默认值
    * undefined就会触发函数参数的默认值。
    * */
    function move({x = 0,y = 0} = {}){
    return [x,y]
    }
    // move({x:3,y:8}) [3,8]
    // move({x:3}) [3,0]
    // move({}) [0,0]
    // move() [0,0]


    // 圆括号问题
    // 解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,
    // 一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。
    //
    // 由此带来的问题是,如果模式中出现圆括号怎么处理。ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号。
    //
    // 但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号。

    /*
    * 以下三种解构赋值不得使用圆括号
    *
    * (1)、变量声明语句,模式不能使用圆括号
    * (2)、函数参数,函数参数也属于变量声明,因此不能带有圆括号
    * (3)、赋值语句的模式
    * */

    /*
    * 可以使用圆括号的情况
    * 赋值语句的非模式部分,可以使用圆括号
    * */

     三、字符串扩展

    //1、字符的unicode表示法
    // 只限于码点在u0000~uFFFF之间的字符

    // 2、codePointAt()
    // 返回一个字符的码点

    // 3、String.formCodePoint()
    //从码点返回对应字符,但是这个方法不能识别32位的UTF-16字符

    // 4、字符串的遍历器接口 for...of

    //5、normalize()

    /*
    * 6、includes() startsWith() endsWith()
    * includes() 返回布尔值,表示是否找到了参数字符串
    * startsWith() 返回布尔值,表示参数字符串是否在原字符串的头部
    * endsWith() 返回布尔值,表示参数字符串是否在原字符串的尾部
    * 三个方法都支持第二个参数,表示开始搜索的位置:
    * endsWith的行为与其他两个方法有所不同。他针对前n个字符,
    * 而其他两个方法针对从第n个位置知道字符串结束
    * */
    let str1 = 'Hello world!';

    console.log(str1.startsWith('Hello'));
    // true
    console.log(str1.endsWith('!'));
    // true
    console.log(str1.includes('o'));
    // true
    console.log(str1.startsWith('world', 6));
    // true
    console.log(str1.endsWith('Hello',5));
    // true
    console.log(str1.includes('Hello',6));
    //false

    /*
    * 7、repeat()
    * 返回一个新字符串,表示将原字符串重复n次
    * (1)、参数如果是小数会被取整
    * (2)、如果参数是负数或者Infinity,会报错
    * (3)、0 到 -1之间视为0
    * (4)、NAN等同于0
    * (5)、参数是字符串,则会先转换成数字
    * */
    console.log('x'.repeat(5));
    // xxxxx
    console.log('x'.repeat(2.9));
    // xx

    /*
    * 8、padStart()、padEnd()
    * 字符串补全长度,如果某个字符串不够指定长度,会在头部或尾部补全。
    * 如果原字符串的长度,等于或大于最大长度,则字符串不全不生效,返回原字符串。
    * 如果用来不全的字符串与原字符串,两者的长度之和超过了最大长度,则会截取超出位数的补全字符串。
    * 如果省略第二个参数,默认使用空格补全长度。
    * 一共接受两个参数,
    * 第一个参数是字符串不全时生效的最大长度,
    * 第二个参数是用来补全的字符串
    * */

    // 9、matchAll()方法返回一个正则表达式在当前字符串的所有匹配

    /*
    * 10、模板字符串 用反引号 ` 标识。
    * 模板字符串中嵌入变量,需要将变量名写在${}之中。
    * 还可以调用函数${f()}
    * ${}里面的变量如果没有声明,会报错
    * ${}里面是字符串将会原样输出
    * 模板字符串中需要使用反引号,则前面要用反斜杠转义
    * 所有的空格和缩进都会被保留在输出之中
    * 如果不想要换行可以使用trim()方法消除
    */


    let greeting = `\`Yo\` World!`;
    console.log(greeting);
    //`Yo` World!
    let name = 'zsh',time = 'today';
    console.log(`Hello ${name},how are you ${time}`)
    // Hello zsh,how are you today
    let list = `
    <ul>
    <li>first</li>
    <li>second</li>
    </ul>
    `.trim();

    console.log(list);

    let oBox = document.getElementsByClassName('box')[0];
    oBox.innerHTML = `<ul>
    <li>Hello ${name},</li>
    <li>how are you ${time}</li>
    </ul>`;
    // 调用函数
    function f(){
    return 'f() 函数调用了'
    }
    console.log(`函数f()返回:${f()}`)

    // 嵌套
    const tmpl = addrs => `
    <table>
    ${addrs.map(addr => `
    <tr><td>${addr.first}</td></tr>
    <tr><td>${addr.last}</td></tr>
    `).join('')}
    </table>
    `;
    const data = [
    { first: '<Jane>', last: 'Bond' },
    { first: 'Lars', last: '<Croft>' },
    ];
    console.log(tmpl(data));


    let a = 5;
    let b = 10;

    tag`Hello ${ a + b } world ${ a * b }`;
    // 等同于
    tag(['Hello ', ' world ', ''], 15, 50);
    function tag(stringArr, value1, value2){
    console.log(arguments)
    }

    /*
    * 11. string.raw()
    * 往往用来充当模板字符串的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,
    * 对应于替换变量后的模板字符串。String.raw`Hi ${2+3}!`;
    * */

    String.raw`Hi ${2+3}!`;
    // 返回 "Hi\n5!"

    String.raw`Hiu000A!`;
    // 返回 "Hi\u000A!"
  • 相关阅读:
    物理好题随想
    学案12:电场强度和静电现象
    vscode插件记录
    windows使用总结
    元素周期律 + 元素周期表
    酸碱理论
    氮族元素——磷
    氮族元素——氮
    碱金属元素
    SDN第一次上机实验
  • 原文地址:https://www.cnblogs.com/zshno1/p/9739629.html
Copyright © 2020-2023  润新知