Es6补充

ES6

块级作用域

  • ES6中的块级作用域 指的是 {} 之间可以生成作用域

let关键字

通过let定义的变量 遵循ES6的块级作用域规范

  • 块级作用域
    if (true) {
        var a = 10;
        let b = 11;
        console.log(a); // 10
        console.log(b); // 11
    }
    console.log(a); // 10
    console.log(b); // 报错
  • 没有变量声明的提升
    console.log(a);  // undefined 因为声明提升
    var a = 10;
    console.log(b); // 报错
    let b = 11; 
    console.log(b);
  • 不可以重复定义同名变量
    var a = 10;
    var a = 11;
    console.log(a); // 可以输出11

    let a = 10;
    let a = 11; // 报错 Uncaught SyntaxError: Identifier 'a' has already been declared
  • let定义的变量不会自动注册到window身上
    var a = 10; // var出来的全局变量会被自动注册成window的属性
    console.log(window.a); // 10

    let a = 10; 
    console.log(a); // 10
    console.log(window.a); // undefined

    console.log(a); // 在不声明a时 会报错
    console.log(window.a); // 有就用 没有就undefined 
  • for循环的不同
    var arr = new Array(5).fill(0);
    for (let i = 0; i < arr.length; i++) {
        arr[i] = function() {
            console.log(i);
        }
    }
    // 如果上面定义循环变量i时使用的是var 则下面代码执行时都输出5 如果用let定义变量 则如下执行
    arr[0](); // 0
    arr[1](); // 1
    arr[2](); // 2
    arr[3](); // 3
    arr[4](); // 4

const关键字

用于定义常量
命名规范: 推荐全部大写 如果出现了单词需要使用_进行分割
ex: const HELLO_WORLD = 10;

  • 值一旦被赋值 不能使用等号改
    const A = 10;
    A = 11; // 报错: Uncaught TypeError: Assignment to constant variable.
    /* 如果常量保存的是引用类型 可以使用方括号语法和点语法进行属性的修改 */
    const OBJ = {};
    OBJ = 123; // 会报错
    OBJ["hello"] = 123;

注:const定义出来的常量也遵守块级作用域 也没有声明提升 也不会注册到window身上 千万不要使用const来定义循环变量

对象的定义简化

对象的定义 可以用字面量 可以用构造函数 ES6中 针对对象的定义 进行了简化

  • 如果对象的属性名和属性值一致 则可以只使用一个
    /* 以前的定义变量 */
    var color = "red"; 
    var obj = {
        color: color
    }

    // 简化后
    var obj = {
        color
    }
    console.log(obj);
  • 现在可以在对象属性定义时通过方括号进行开辟JS执行环境
    var he = "he";
    var llo = "world";
    var obj = {
        hello: "",
        [he + llo]: ""
    }
  • 定义方法时 可以省略 : function
     var obj = {
        a: 1,
        hello: function() {
            console.log("hello");
        },
        world() {
            console.log("world");
        }
    }
    console.log(obj.a);
    obj.hello(); // hello
    obj.world(); // world

解构语法

提到解构,就不得不提封装

  • 封装 封装指的是将内容包装在一起

    • 代码封装 使用函数
    • 数据封装 使用数据结构 目前为止我们学习的数据结构一共有两种 分别是数组和对象
  • 解构 指的是解除构造\解除结构(换句话说就是,你封装的,我给你拆了)

解构数组

  • 人工解构
    // 定义数组
    var arr = [1, 2, 3, 4, 5];
    // 人工解除结构
    var a = arr[0];
    var b = arr[1];
    var c = arr[2];
    var d = arr[3];
    var e = arr[4];
  • ES6语法解构
    // 定义数组
    var arr = [1, 2, 3, 4, 5];
    // 解构语法
    var [a, b, c, d, e] = arr;

解构对象

  • ES6语法解构
    // 解构对象
    var obj = {
        username: "zhangsan",
        password: "123321",
        dog: {
            name: "xiaobai"
        }
    }
    var {password, username, dog} = obj;
    console.log(username, password, dog);

注: 数组解构,是用下标一一对应,所以要注意顺序。 对象解构,是使用属性名对应,所以不用注意顺序,但是要注意属性名是否对应。

多行字符串

在ES6之前 所有的字符串只能是单行字符串 单引号与双引号定义的都是单行

  • 定义语法
    • ES6定义多行字符串方式 ``
    • 按键位置: 横向数字键1左侧 tab键上侧 esc键下方
  • 插值语法
    • ${}
      注: ${}内是一个JS执行环境,可以放变量,可以放表达式,可以调用方法
    var str = `
        
${username}
${password}
${email}
`;

函数中的this

function定义的函数中的this,是可以变化的,遵循的规则是: 谁调用就指向谁, 如果没有明确的调用者,则指向window

  • 会变化的this
    
    function demo() {
        console.log(this);
    }

    // 自己执行 
    demo(); // window

    document.onclick = demo; // document

    var obj = {
        demo
    }

    obj.demo(); // obj

    setInterval(demo, 1000); // window
    setTimeout(demo, 1000); // window

改变函数中this指向的方法

这三个都是函数的方法

  • call
    call可以调用函数 它的作用是执行函数并改变函数中的this指向 如果原函数需要参数 需要往call的参数列表中传递 第一个参数是this 往后的每一个参数是原函数所需参数
    function sum(a, b) {
        console.log(this);
        console.log(a, b);
    }

    sum.call(); // 不传递参数时 this指向window a和b 都是undefined
    sum.call(document);//  this指向了document a 和 b都是undefined
    sum.call(document.body, 1);// this指向body a时1 b是undefined
    sum.call(document.body, 1, 3);// this指向body a时1 b是3
  • apply
    apply可以调用函数 它的作用是执行函数并改变函数中的this指向 如果原函数需要参数 需要往apply的参数列表中传递 第一个参数是this 第二个参数是数组 数组中的每一个成员是原函数所需的参数 按照数组顺序一一对应
    function sum(a, b) {
        console.log(this);
        console.log(a, b);
    }
    sum.apply(); // 不传递参数时 this指向window a和b 都是undefined
    sum.apply(document); // this指向了document a 和 b都是undefined
    sum.apply(document, [1]); // this指向了document a 是 1 b 是undefined
    sum.apply(document, [1, 3]); // this指向了document a 是 1 b 是 3
  • bind
    bind 是ES5中新增的方法 作用是在定义的时候改变this指向(其实是返回了一个新的函数)
    function sum(a, b) {
        console.log(this);
        console.log(arguments);
    }
    // 调用bind方法
    var fun = sum.bind(document, 1, 2, 0.4, 0.5, 0.6);
    // fun是一个函数 
    fun(3, 4, 5, 6, 7);
    console.log(sum === fun); // false

箭头函数

ES6中新增的一种函数定义方式
箭头函数 var name = () => {}

  • demo
    var fun = () => {
        console.log("hello 我是一个箭头函数");
    }
    fun(); // hello 我是一个箭头函数
    console.log(typeof fun); // function
  • 箭头函数中的this
    箭头函数中的this 只有在定义箭头函数时能够确定 而且一旦确定再也不会更改
    let fun = () => {
        console.log(this);
    }
    fun(); // window
    document.onclick = fun; // 依然是window
    let obj = {
        fun
    }
    obj.fun(); // window
    fun.call(document.body); // window
    fun.apply(document.documentElement); // window
    var fun1 = fun.bind(document);
    fun1(); // window

总结:经过各种测试 我们发现无论如何 箭头函数中的this是不会发生变化的

  • 函数的参数默认值
    function fun(a = [], b = {}) {
        console.log(a, b);
    }
    fun(); // 不传递参数 但是因为在定义形参时 通过赋值语法进行了默认值的赋值 所以依然可
    fun(0); // 一旦传递了参数 不论传递的是什么 传递了值的参数 将不会再使用默认值
    fun("a0", "b1");
    箭头函数中依旧如上写法
  • 函数中没有arguments
    let fun = () => {
        console.log(arguments); 
    }
    fun(); // 报错 
  • 箭头函数的简写形式
    • 如果参数只有一个 那么可以省略圆括号
    • 如果函数体中只有一条代码并且还是返回值 则可以省略大括号 和return
    var fun = x => x * x * x * x;
    var result = fun(5);
    console.log(result); // 625

拓展语法(…)

  • 作用1 作为函数的参数收集器
    // ...语法作用之一: 获取参数为数组
    let fun = (...a) => {
        console.log(a);
    }
    fun(); 
    fun(1); 
    fun(1, 2); 
    fun(1, 2, 3); 
  • 作用2 解构时使用
    var arr = "abcdefg".split("");
    console.log(arr); // ["a","b","c","d","e","f","g"]
    var [a,b,c, ...d] = arr;
    console.log(a, b, c); // a b c
    console.log(d); // ["d","e","f","g"]
  • 作用3 传递参数时使用
    var arr = "abcdefg".split("");
    var [a,b,c, ...d] = arr;
    console.log(arr);
    console.log(d);
    // 将arr数组中最后一项 “g”去掉 并将d数组中 ["d", "e", "f", 
    arr.splice(arr.length - 1, 1, ...d);
    console.log(arr); // ["a","b","c","d","e","f","d","e","f","g"]

额外补充

  • 能力检测
    // getComputedStyle  能力检测 利用的就是从对象身上读取属性 无论如何都不会报错的特点
    if (window.getComputedStyle) {

    } else {

    }
  • bind方法的实现
    // 定义一个函数 
    function sum(a, b) {
        console.log(this);
        console.log(arguments);
    }
    // 模拟bind方法
    function bind(sum, target) {
        var arr = [].slice.call(arguments, 2);
        return function() {
            var arr1 = [].slice.call(arguments);
            sum.apply(target, arr.concat(arr1));
        }
    }
    var fun = bind(sum, document.body, 1, 26, 7, 8, 9);
    fun(10, 11, 12, 13);  // this指向document.body 参数为 [1, 26, 7, 8, 9, 10, 11, 12, 13]

你可能感兴趣的:(js原生)