es6 学习笔记-1

学习视频:尚硅谷Web前端ES6教程,涵盖ES6-ES11_哔哩哔哩_bilibili

一、介绍 

ES:全称为EcmaScript,是脚本语言的规范

ECMAScript: 由Ecma国际通过ECMA-262标准化的脚本程序设计语言。

es6兼容性ECMAScript 6 compatibility table

二、ES6 - 声明变量

(一)let 

1.不能重复声明;(var可以重复声明)

2.块级作用域;

3.不存在变量提升;(变量提升解释:代码执行之前收集变量名称,最初为undefined)

        console.log(abc);  var abc = 'aaa';  ==》 输出undefined

        console.log(abc);  let abc = 'aaa';  ==》 报错

4.不影响作用域链;

举例:

<script>
			let items = document.getElementsByClassName('item');
			for (var i = 0; i < items.length; i++) {
				items[i].onclick = function() {
					this.style.background = 'pink'; //必须用this,因为i此时为3,
                                                    //items[i]会报错
				}
				
			}
</script>
<script>
			let items = document.getElementsByClassName('item');
			for (let i = 0; i < items.length; i++) {
				items[i].onclick = function() {
					items[i].style.background = 'pink'; //可以用items[i]或this
				}
				
			}
</script>

(二) const 声明常量

1. 一定要赋初始值

 2.一般常量使用大写

3.常量的值不能修改


			const SCHOOL = '测试';
			SCHOOL = 'ABC';
//报错:Uncaught SyntaxError: Missing initializer in const declaration

4.块儿级作用域

{
	const SCHOOL1 = '测试';
}
console.log(SCHOOL1);
//报错:Uncaught ReferenceError: SCHOOL1 is not defined at 2-const.html:23

5.对于数组和对象的元素修改,不算做对常量的修改,不会报错

const TEAM = ['ABC','MING','ADF'];
TEAM.push('AD'); //地址不变,所以不报错
TEAM = 100; //会报错

三、ES6 - 变量的解构赋值

允许按照一定模式从数组和对象中提取值,对变量进行赋值,被称为解构赋值。

<script>
			//1.数组的解构
            const F4 = ["言承旭","周渝民","没组","西门"];
            let [yan,zhou,mei,xi] = F4;
            console.log(mei,zhou,yan,xi);
            //2.对象的解构
            const zhao={
                name:'赵本山',
                age:55,
                xiaopin:function(){
                    console.log("我可以演小品");
                }
            };
            let {name,age,xiaopin}=zhao;
            console.log(age,name,xiaopin);
            xiaopin();

		</script>

四、ES6 - 模板字符串

<script>
			//ES6引入新的声明字符串的方式[``] '' ""
            //1.声明
            let str = '我也是一个字符串';
            console.log(str, typeof str); //输出:我也是一个字符串 string
            //2.内容中可以直接出现换行符
            str = `<ul>
                <li>aa</li>
                <li>bb</li>
                </ul>`;
            //3.变量拼接
            let lovest = '天才樱木';
            let out = `${lovest}不是傻瓜`;
            console.log(out);  //输出:天才樱木不是傻瓜
		</script>

五、ES6 - 对象的简化写法

ES6允许在大括号里,直接写入变量和函数,作为对象的属性和方法。

<script>
			//ES6允许在大括号里,直接写入变量和函数,作为对象的属性和方法。
            let name = '加油';
            let change = function(){
                console.log('我们可以改变');
            }
            const school1 = {  // 完整写法
                name:name,
                change:change,
                inporove: function(){
                    console.log('我们要努力学习');
                }
            };
            const school = {  //简略写法,只写变量
                name,
                change,
                improve(){
                    console.log('我们要努力学习');
                }
            };
            console.log(school); //输出:{name: '加油', change: ƒ, improve: ƒ}
		</script>

输出:

六、ES6 - 箭头函数以及声明特点

(一)、允许使用箭头 (=>) 定义函数

	<script>
			//允许使用箭头 (=>) 定义函数
            //声明函数
            let fn = function(){ //旧写法
                
            }
            let fn1 = (a,b)=>{
                return a+b;
            }
            //调用函数
            let result = fn1(1,2);
            console.log(result);
            //1.this是静态的,this始终指向函数声明时所在作用域下的this的值
            function getName(){
                console.log(this.name);
            }
            let getName2 = () => {
                console.log(this.name);
            }
            //设置window的name属性
            window.name='test';
            const school = {
                name:"TEST"
            }
            //直接调用
            getName(); //out:test //this指向window
            getName2(); //out:test //this指向window

            //call方法调用
            getName.call(school); //TEST
            getName2.call(school); //test

            //2.不能作为构造函数实例化对象
            // let Person = (name, age) => {
            //     this.name = name;
            //     this.age = age;
            // }
            // let me = new Person('xiao',30);
            // console.log(me); //error : Uncaught TypeError: Person is not a constructor
	
            //3.不能使用arguments变量
            // let fn2 = ()=>{
            //     console.log(arguments); //error:Uncaught ReferenceError: arguments is not defined
            // }
            // fn2(1,2);

            //4.箭头函数的简写
            //  a.省略小括号:当形参有且只有一个
            // let add1 = (n) => {
            //     return n+n;
            // }
            let add = n => {
                return n+n;
            }
            console.log(add(9));
            //  b.省略花括号:当代码体只有一条语句: return必须省略
            // 而且语句的执行结果时函数的返回值
            // let pow = (n) => {
            //     return n*n;
            // }
            let pow = n => n*n;
            console.log(pow(8));
    </script>

call方法扩展说明:call() 方法是预定义的 JavaScript 方法,它可以用来调用所有者对象作为参数的方法。通过 call(),您能够使用属于另一个对象的方法。

var person = {
    fullName: function() {
        return this.firstName + " " + this.lastName;
    }
}
var person1 = {
    firstName:"Bill",
    lastName: "Gates",
}
var person2 = {
    firstName:"Steve",
    lastName: "Jobs",
}
person.fullName.call(person1);  // 将返回 "Bill Gates"

call() 方法可接受参数:

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"Bill",
  lastName: "Gates"
}
person.fullName.call(person1, "Seattle", "USA"); //out:Bill Gates,Seatle,USA

arguments扩展说明:arguments 是一个对应于传递给函数的参数的类数组对象。arguments 实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参。

arguments展示形式是一个伪数组:具有 length 属性,按索引方式储存数据,不具有数组的 push , pop 等方法。

函数参数(argument)指的是传递到函数或由函数接收到的真实

如果调用参数时省略了参数(少于被声明的数量),则丢失的值被设置为:undefined

function sumAll() {
  var i;
  var sum = 0;
  for(i = 0; i < arguments.length; i++) {
    sum += arguments[i];
  }
  return sum;
}
console.log(sumAll(1,2,4)); // out:7

(二)、箭头函数举例

1. 点击div 2s后变色

<script>
			//需求:1-点击div 2s 后颜色变了
            let ad = document.getElementById('ad');
            //绑定事件
            ad.addEventListener("click", function(){
                // a.this报错 
                // setTimeout(function(){
                //     console.log(this); //out: window
                //     this.style.background = 'pink'; //error:Uncaught TypeError: Cannot set properties of undefined (setting 'background')
                // },2000);

                // b.老的正确写法: 保存this的值
                // let _this = this;
                // setTimeout(function(){
                //     console.log(this); 
                //     _this.style.background = 'pink'; 
                // },2000);

                //c. 箭头函数写法:this是静态的,指向声明的函数的作用域的值
                setTimeout(()=>{
                    this.style.background = 'pink';
                },2000);
                
            })
        </script>

2. 从数组中返回偶数元素

// 2.需求-2 从数组中返回偶数的元素
            const arr = [1,6,9,10,100,25];
            //a. 老方法
            const result = arr.filter(function(item){
                if(item % 2 === 0) {
                    return true;
                }else {
                    return false;
                }
            });
            console.log(result); //out:(3) [6, 10, 100]
            //b. 箭头函数
            const result1 = arr.filter(item => item % 2 === 0);
            console.log(result1); //out:(3) [6, 10, 100]

总结:箭头函数适合于this无关的回调,如定时器,数组的方法回调

           不适合与this有关的回调,如事件回调,对象的方法

            let a={
                name:'abc',
                getName : function(){  
                    return this.name;  //this 指向本对象
                }
            };
            var name = 'cccc'; //或window.name可以输出 //当let name='xx'时无法输出,为什么?
            let b ={
                name:'abc',
                getName : ()=> {
                    console.log(this); //window
                    return this.name;
                } //指向外层this
            };
            console.log(a.getName()); // out: abc
            console.log(b.getName()); // out: cccc                       

七、ES6 - 函数参数的默认值

es6允许给函数参数赋初始值

        <script>
			//es6允许给函数参数赋初始值
            //1.形参初始值
            //具有默认值的参数,一般位置要靠后
            function add(a,b,c=10) {
                return a+b+c;
            }
            console.log(add(1,2),add(1,2,3)); //out: 13 6
            //2. 与解构赋值结合
            function connect(options) { //传统写法
                let host = options.host;
                let username = options.username;
                console.log(host,username);//out:localhost root
            }
            function connect({host,username,password,port}){ //解构写法
                console.log(host,username,password,port);
            }
            connect({
                host:'localhost',
                username:'root',
                password:'root',
                port:3306
            }) //out:localhost root root 3306

            //解构写法+赋初始值
            function connect1({host='127.0.0.1',username,password,port}){
                console.log(host,username,password,port);//out:localhost root root 3306
            }
            connect1({
                username:'root',
                password:'root',
                port:3306
            }) //out:127.0.0.1 root root 3306
		</script>

八、ES6 - rest参数

        <script>
			//es6 引入 rest参数,用于获取函数的实参,用来代替arguments
            //es5 获取实参的方式
            function date(){
                console.log(arguments);
            }
            date('abc','23','adf'); //out:Arguments(3)对象 0: "abc" 1: "23" 2: "adf"
            //es6 rest参数
            function date1(...args){
               console.log(args);     
            }
            date1('abc','23','adf'); //out: (3) ['abc', '23', 'adf'] //是数组
            //rest参数必须放到参数最后
            function fn(a,b,...args){
                console.log(a,b,args);
            }
            fn(1,2,3,4,5); //out:1 2 (3) [3, 4, 5] //3,4,5属于一个数组,给了args
        </script>

九、ES6 - 扩展运算符

(一)、扩展运算符介绍

      <script>
		// ... 扩展运算符能将 数组 转换为逗号分隔的 参数序列
        //声明一个数组
        const boys = ['ab','cd','ef']; //=>'ab','cd','ef'
        //声明一个函数
        function chunwan(){
            console.log(arguments);
        }
        chunwan(boys); //out:Arguments(1) // 0: (3) ['ab', 'cd', 'ef'] //只有一个数组参数
        chunwan(...boys);// out:Arguments(3) // 0: "ab" 1: "cd" 2: "ef" //变成三个参数
                         // 等同于chunwan('ab','cd','ef')
       </script>

(二)、扩展运算符的应用

<html>
	<head>
		<meta charset="UTF-8">
		<title>let</title>
	</head>
	<body>
        <div></div>
        <div></div>
        <div></div>
		<script>
        //应用:1. s数组的合并
        const str1 = ['a1','a2'];
        const str2 = ['b1','b2'];
        const unit = str1.concat(str2);
        console.log(unit); //out:(4) ['a1', 'a2', 'b1', 'b2'] //数组
        //扩展运算符
        const unit2 = [...str1, ...str2];
        console.log(unit2);//out:(4) ['a1', 'a2', 'b1', 'b2'] //数组
        //2. 数组的克隆
        const sanzhihua = ['e','g','m'];
        const sanyecao = [...sanzhihua];
        console.log(sanyecao);//out : (3) ['e', 'g', 'm'] //如果元素包含引用类型,则是浅拷贝
        //3. 将伪数组转为真正的数组
        const divs = document.querySelectorAll('div');
        console.log(divs); //out : NodeList(3) [div, div, div] //对象
        const divArr = [...divs];
        console.log(divArr);//out:(3) [div, div, div]
       </script>
	</body>
	
</html>

十、 ES6 - Symbol

(一)、介绍和创建

   Symbol是新引入的数据类型,表示独一无二的值,类似于字符串的数据类型。

特点:1.Symbol值是唯一的,解决命名冲突的问题。2.Symbol值不能与其他数据进行运。                         3.Symbol定义的对象属性不能使用for...in循环遍历,可以用Reflect.ownKeys来获取对象的所有键名

 //创建Symbol
        let s = Symbol();
        console.log(s,typeof s); //out: Symbol() 'symbol'
        
        let s2 = Symbol('abc');//传入描述字符串
        let s3 = Symbol('abc');
        console.log(s2 === s3); // out : false

        let s4 = Symbol.for('abc');
        console.log(s4,typeof s4); // out: Symbol(abc) 'symbol'

        let s5 = Symbol.for('abc');
        console.log(s4 === s5); // out: true
       
        //不能与其他数据进行运算
        // let result = s + 100; //error: Uncaught TypeError: Cannot convert a Symbol value to a number
        // let result = s + s; //error: Uncaught TypeError: Cannot convert a Symbol value to a number

      

     七种数据类型口诀USONB  you are so niubility 
        //u undefined
        //s string symbol
        //o object
        //n null number
        //b boolean    

(二)symbol使用场景

        //2 - 使用场景: 向对象中添加方法 up down
        let game = {
            name:'abc',
            up:function(){},
            down:function(){}
        }
        // game.up = function(){}
        //声明一个对象
        let methods = {
            up:Symbol(),
            down:Symbol()
        };
        game[methods.up] = function(){
            console.log('我可以改变形状');
        }
        game[methods.down] = function(){
            console.log('我可以快速下降');
        }
        console.log(game);//out : {name: 'abc', up: ƒ, down: ƒ, Symbol(): ƒ, Symbol(): ƒ}

        let youxi = {
            name:'狼人杀',
            [Symbol('say')]:function(){
                console.log('abc');
            },
            [Symbol('zibao')]:function(){
                console.log('efg');
            },
        }
        console.log(youxi);//out:{name: '狼人杀', Symbol(say): ƒ, Symbol(zibao): ƒ}

输出:

  1. {name: '狼人杀', Symbol(say): ƒ, Symbol(zibao): ƒ}
    1. name: "狼人杀"
    2. Symbol(say): ƒ ()
      1. arguments: null
      2. caller: null
      3. length: 0
      4. name: "[say]"
      5. prototype: {constructor: ƒ}
      6. [[FunctionLocation]]: 10-symbol.html:63
      7. [[Prototype]]: ƒ ()
      8. [[Scopes]]: Scopes[2]
    3. Symbol(zibao): ƒ ()
    4. [[Prototype]]: Object

(三)Symbol-内置值

除了定义自己使用的Symbol值以外,es6还提供了11个内置的Symbol值,指向语言内部使用的方法

Symbol其他扩展介绍可以参考:

2.3 ES6 Symbol | 菜鸟教程

Symbol - JavaScript | MDN

//当其他对象使用instanseof运算符,判断是否为该对象的实例时,会调用这个方法
      class Person{
        static [Symbol.hasInstance](param){
            console.log(param); // out: {}
            console.log('检测类型');
        }
      }
      let o = {};
      console.log(o instanceof Person);//out:false


      //对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,
      //是否可以展开。
      const arr = [1,2,3];
      const arr2 = [4,5,6];
      console.log(arr.concat(arr2));//out: (6) [1, 2, 3, 4, 5, 6]

      arr2[Symbol.isConcatSpreadable] = false;
      console.log(arr.concat(arr2));//out:(4) [1, 2, 3, Array(3)]

十一、迭代器

(一)迭代器介绍

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,九可以完成遍历操作。

1)es6创造了一种新的遍历命令for..of循环,iterator接口主要供for..of消费

2)原生具备iterator接口 数据(可用for of遍历)

Array, Arguments, Set, Map, String, TypedArray, NodeList

3) 工作原理

a)创建一个指针对象,指向当前数据结构的起始位置

b)第一次调用对象的 next方法,指针自动指向数据结构的第一个成员

c)接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员

d)每调用next方法返回一个包含value和done属性对象

 //声明一个数组
       const arr = ['a','b','c','d'];
       for (let v in arr) {
        console.log(v+"-"+arr[v]); // out: 0-a 1-b 2-c 3-d
       }
       //使用for...of遍历数组
       for (let v of arr) {
        console.log(v); // out: a b c d
       }
       console.log(arr);
       let iterator = arr[Symbol.iterator]();
       console.log(iterator);//out:Array Iterator {}

       //调用对象的next方法
       console.log(iterator.next());//out:{value: 'a', done: false}
       console.log(iterator.next());//out:{value: 'b', done: false}
       console.log(iterator.next());//out:{value: 'c', done: false}
       console.log(iterator.next());//out:{value: 'c', done: false}
       console.log(iterator.next());//out:{value: undefined, done: true}

(二)迭代器应用

注意:需要自定义遍历数据的时候,需要想到迭代器。

  //2 -应用
       //注意:需要自定义遍历数据的时候,需要想到迭代器。
       const banji = {
        name:"终极一班",
        stus:[
            'marry',
            'summer',
            'rukawa',
            'sakuragi',
            'lucy'
        ],
        [Symbol.iterator](){
            let index = 0;
            let _this = this;
            return {
                next:function(){
                    if(index < _this.stus.length) {
                        const result =  {value:_this.stus[index],done:false};
                        //下标自增
                        index++;
                        return result;
                     }else {
                        return {value:undefined, done:true};
                     }
                }
            };
        }
       }
       //遍历对象,每一次返回的结果是数组里的成员
       for (let v of banji) {
        console.log(v);//marry summer rukawa sakuragi lucy
       }

十二、生成器

生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数不同

(一)声明和调用

//异步编程 纯回调函数:node fs ajax mongodb

       //加一个星号
       function * gen(){
        console.log('hello');
       }
       let iterator = gen();
       console.log(iterator);
       /**
        * out:
        * gen
            [[GeneratorLocation]]: 12-生成器.html:13
            [[Prototype]]: Generator
                [[Prototype]]: Generator
                    constructor: GeneratorFunction {prototype: Generator, Symbol(Symbol.toStringTag): 'GeneratorFunction', constructor: ƒ}
                    next: ƒ next()
                    return: ƒ return()
                    throw: ƒ throw()
                    Symbol(Symbol.toStringTag): "Generator"
                    [[Prototype]]: Object
            [[GeneratorState]]: "suspended"
            [[GeneratorFunction]]: ƒ * gen()
            [[GeneratorReceiver]]: Window
            [[Scopes]]: Scopes[3]
        * 
       */
      iterator.next(); //out: hello

      //yidld函数代码的分隔符
      function * gen1(){
        console.log(111);
        yield '一个';
        console.log(222);
        yield '二个';
        console.log(333);
        yield '好的吧';
        console.log(444);
      }
      let it = gen1();
      console.log(it.next());//out:111 {value: '一个', done: false}
      console.log(it.next());//out:222 {value: '二个', done: false}
      console.log(it.next());//out:333 {value: '好的吧', done: false}
      console.log(it.next());//out:444 {value: undefined, done: true}

      //遍历
      for(let v of gen1()){
        console.log(v); 
      }
      /**
       * out:
            111
            一个
            222
            二个
            333
            好的吧
            444
       * 
      */

(二)生成器的参数传递

  //2-生成器的参数传递
     function * abc(arg){
        console.log(arg);
        let one = yield 111;
        console.log(one);
        let two = yield 222;
        console.log(two);
        let three = yield 333;
        console.log(three);
     }
     //执行获取迭代器对象
     let iterator1 = abc('aaa');
     console.log(iterator1.next()); // aaa  {value: 111, done: false}
     //next 方法可以传入实参
     console.log(iterator1.next('bbb'));//bbb  {value: 222, done: false}
     console.log(iterator1.next('ccc'));//ccc  {value: 333, done: false}
     console.log(iterator1.next('ddd'));//ddd  {value: undefined, done: true}
   

(三)生成器函数实例

 //3-实例1
    //异步编程:文件操作 网络操作(ajax,request) 数据库操作
    //1s 后控制台输出 111  2s后输出222  3s后输出333
        //老代码:回调地狱
        setTimeout(() => {
            console.log(111);
            setTimeout(() => {
                 console.log(222);
                 setTimeout(() => {
                      console.log(333);
                 }, 1000);
              }, 1000);
        }, 1000);
        console.log("---------------------------");
        //改进
        function one(){
            setTimeout(()=>{
                console.log(111);
                it1.next();
            },1000)
        }
        function two(){
            setTimeout(()=>{
                console.log(222);
                it1.next();
            },1000)
        }
        function three(){
            setTimeout(()=>{
                console.log(333);
                it1.next();
            },1000)
        }
        function * create1(){
            yield one();
            yield two();
            yield three();
        }
        //调用生成器函数
        let it1 = create1();
        it1.next();
 //3-实例2
    //模拟获取 用户数据 订单数据 商品数据
    function getUsers(){
        setTimeout(() => {
            let data1 = '用户数据';
            //调用next方法,并且将数据传入
            it2.next(data1);
        }, 1000);
    }
    function getOrders(){
        setTimeout(() => {
            let data = '订单数据';
            it2.next(data);
        }, 1000);
    }
    function getGoods(){
        setTimeout(() => {
            let data = '商品数据';
            it2.next(data);
        }, 1000);
    }
    function * create2(){
        let users = yield getUsers();
        console.log(users);
        let orders = yield getOrders();
        console.log(orders);
        let goods =  yield getGoods();
        console.log(goods);
    }
    //调用生成器函数
    let it2 = create2();
    it2.next();

十三、Promise

(一)介绍

Promise是es6引入的异步编程的新解决方案,语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

构造函数:Promise(excutor){}

Promise.prototype.then方法

Promise.prototype.catch方法

//实例化promise对象
        //初始化 成功 失败
        const p = new Promise(function(resolve,reject){
            setTimeout(function(){
                
                // let data = '数据库中的用户数据';
                // //resolve
                // resolve(data);  //成功时调用

                let err = '数据读取失败';
                reject(err);      //失败时调用
            },
            1000);
        });
        //调用promise 对象的 then方法
        p.then(function(value){ //成功
            console.log(value);  // out: 数据库中的用户数据
        },function(reason){//失败
            console.log(reason); // out: 数据读取失败
        })

(二) 封装读取文件

// //1.引入fs模块
const fs = require('fs');
// //2. 调用方法读取文件
// fs.readFile('../resources/1.txt',(err,data)=>{
//     //如果失败,抛出错误
//     if(err) throw err;
//     //如果正确,则输出
//     console.log(data.toString());
// });
//3.使用promise封装
const p = new Promise(function(resolve, reject){
    fs.readFile('../resources/1.txt',(err,data)=>{
        //如果失败
        if(err) reject(err);//改变状态为失败
        //如果正确,改变状态为成功,并传值
       resolve(data);
    });
});

p.then(function(value){
    console.log(value.toString());
},function(reason){
    console.log('读取失败');
});

控制台输入:node .\13-promise读取文件.js

打印出文件内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值