ES5+ES6全部语法包含案例

发布于:2022-12-23 ⋅ 阅读:(648) ⋅ 点赞:(0)

面向对象:

面向过程 POP:

分析解决问题的步骤,然后用函数把这些步骤一步一步的实现,使用的时候在一个一个依次调用

优点:性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机

缺点:没有面向对象易维护、易复用、易扩展

面向对象OPP:

把事务分解成对象的形式,看看对象有什么功能,再把功能使用起来

优点:灵活、代码可复用、容易维护和开发,适合多人合作的大型项目

特性:封装性、继承性、多态性

类和对象:

类:ES6新增加的概念,可以使用class关键字声明一个类,之后以这个类来实例化对象

类抽象了对象的公共部分,它泛指某一大堆(class)

1.创建类

 class Star{
     constructor(uname,age){
         this.uname=uname;
         this.age=age;
     }
 }

.利用类创建对象new,new会自动执行constructor构造函数

var ldh=new Star('刘德华');
console.log(ldh.uname) //刘德华

var zxy=new Star('张学友',20)
console.log(zxy)//uname:张学友,age:20

(1) 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写

(2) 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象

(3) constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数

(4) 生成实例 new 不能省略

(5) 最后注意语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function

2.类中添加方法

class Star{
     constructor(uname,age){
         this.uname=uname;
         this.age=age;
     }
       sing(song){
         console.log(this.uname+song);
     }
 }
    var ldh=new Star('刘德华');
	console.log(ldh.uname)

	var zxy=new Star('张学友',20)
	console.log(zxy)

	ldh.sing('冰雨')//刘德华冰雨
	zyx.sing('李香兰')//张学友李香兰

(1)类里面不需要写function

(2)多个函数方法之间不需要添加逗号分隔

3.类的继承


        class Father {
             constructor() {

             }
            money() {
                console.log(100);

            }
         }
         class Son extends Father { //使用extends继承 

         }
         var son = new Son();
         son.money();
	class Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y);

            }
        }
        class Son extends Father {
            constructor(x, y) {
                super(x, y); //调用了父类中的构造函数
            }
        }
        var son = new Son(1, 2);
        var son1 = new Son(11, 22);
        son.sum();
        son1.sum();

super关键字用于访问和调用父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数

 class Father {
            say() {
                return '我是爸爸';
            }
        }
        class Son extends Father {
            say() {
                // console.log('我是儿子');
                console.log(super.say() + '的儿子');
                // super.say() 就是调用父类中的普通函数 say()
            }
        }
        var son = new Son();
        son.say();
        // 继承中的属性或者方法查找原则: 就近原则
        // 1. 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
        // 2. 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)

扩展运算符继承

class Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y);
            }
        }
        // 子类继承父类加法方法 同时 扩展减法方法
        class Son extends Father {
            constructor(x, y) {
                // 利用super 调用父类的构造函数
                // super 必须在子类this之前调用
                super(x, y);
                this.x = x;
                this.y = y;

            }
            subtract() {
                console.log(this.x - this.y);

            }
        }
        var son = new Son(5, 3);
        son.subtract();
        son.sum();

类的注意事项:

1. 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象

2. 类里面的共有的属性和方法一定要加this使用

构造函数和原型:

1、利用构造函数创建对象

// 1. 利用 new Object() 创建对象

        var obj1 = new Object();

        // 2. 利用 对象字面量创建对象

        var obj2 = {};

        // 3. 利用构造函数创建对象
        function Star(uname, age) {
            this.uname = uname;
            this.age = age;
            this.sing = function() {
                console.log('我会唱歌');

            }
        }

        var ldh = new Star('刘德华', 18);
        var zxy = new Star('张学友', 19);
        console.log(ldh);
        ldh.sing();
        zxy.sing();

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量初始值,它总与new一起使用,我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面

在JS中,使用构造函数时,要注意以下两点:

1.构造函数用于创建某一类对象,其首字母要大写

2.构造函数要和new一起使用才有意义

new在执行时会做四件事情:

1.在内存中创建一个新的空对象

2.让this指向这个新的对象

3.执行构造函数里面的代码,给这个新对象添加属性和方法

4.返回这个新对象(所以构造函数里面不需要return)

原型,原型链:

构造函数通过原型分配的函数是所有对象所共享的

JS规定,每一个构造函数都有一个prototype属性,指向另一个对象,prototype就是一个对象,这个对象的所有属性和方法都会被构造函数所拥有;

我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法;

原型是一个对象,它可以共享方法,不会浪费内存

  // 1. 构造函数的问题. 
        function Star(uname, age) {
            this.uname = uname;
            this.age = age;
            // this.sing = function() {
            //     console.log('我会唱歌');

            // }
        }
        Star.prototype.sing = function() {
            console.log('我会唱歌');
        }
        var ldh = new Star('刘德华', 18);
        var zxy = new Star('张学友', 19);
        console.log(ldh.sing === zxy.sing);
        // console.dir(Star);
        ldh.sing();
        zxy.sing();
        // 2. 一般情况下,我们的公共属性定义到构造函数里面, 公共的方法我们放到原型对象身上

对象原型proto

对象都会有一个属性proto指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype 原型对象的属性和方法,就是因为有proto的存在

proto和prototype是等价的

原型constructor:

function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        // 很多情况下,我们需要手动的利用constructor 这个属性指回 原来的构造函数
        // Star.prototype.sing = function() {
        //     console.log('我会唱歌');
        // };
        // Star.prototype.movie = function() {
        //     console.log('我会演电影');
        // }
        Star.prototype = {
            // 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
            constructor: Star,
            sing: function() {
                console.log('我会唱歌');
            },
            movie: function() {
                console.log('我会演电影');
            }
        }
        var ldh = new Star('刘德华', 18);
        var zxy = new Star('张学友', 19);
        console.log(Star.prototype);
        console.log(ldh.__proto__);
        console.log(Star.prototype.constructor);
        console.log(ldh.__proto__.constructor);

原型链

function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        Star.prototype.sing = function() {
            console.log('我会唱歌');
        }
        var ldh = new Star('刘德华', 18);
        // 1. 只要是对象就有__proto__ 原型, 指向原型对象
        console.log(Star.prototype);
        console.log(Star.prototype.__proto__ === Object.prototype);
        // 2.我们Star原型对象里面的__proto__原型指向的是 Object.prototype
        console.log(Object.prototype.__proto__);
        // 3. 我们Object.prototype原型对象里面的__proto__原型  指向为 null

原型、原型链的总结:

原型:每一个构造函数都有一个prototype属性指向一个对象,这个对象就是构造函数实例的原型

原型链:每一个实例都有一个proto属性指向原型对象,来获取原型对象上的属性和方法,原型对象也有一个proto属性指向另外一个原型对象,以此类推,直到原型链的最终端null为止,这个串成链的过程就是原型链

扩展内置对象方法:

// 原型对象的应用 扩展内置对象方法

        Array.prototype.sum = function() {
            var sum = 0;
            for (var i = 0; i < this.length; i++) {
                sum += this[i];
            }
            return sum;
        };
        // Array.prototype = {
        //     sum: function() {
        //         var sum = 0;
        //         for (var i = 0; i < this.length; i++) {
        //             sum += this[i];
        //         }
        //         return sum;
        //     }

        // }
        var arr = [1, 2, 3];
        console.log(arr.sum());
        console.log(Array.prototype);
        var arr1 = new Array(11, 22, 33);
        console.log(arr1.sum());

改变this指向: call

 // call 方法
        function fn(x, y) {
            console.log('我想喝手磨咖啡');
            console.log(this);
            console.log(x + y);


        }
        var o = {
            name: 'andy'
        };
        // fn();
        // 1. call() 可以调用函数
        // fn.call(); 也可以调用函数
        // 2. call() 可以改变这个函数的this指向 此时这个函数的this 就指向了o这个对象
        fn.call(o, 1, 2);

利用父构造函数继承:

// 借用父构造函数继承属性
        // 1. 父构造函数
        function Father(uname, age) {
            // this 指向父构造函数的对象实例
            this.uname = uname;
            this.age = age;
        }
        // 2 .子构造函数 
        function Son(uname, age, score) {
            // this 指向子构造函数的对象实例
            Father.call(this, uname, age);
            this.score = score;
        }
        var son = new Son('刘德华', 18, 100);
        console.log(son);

用call在Son构造函数里面调用了Father构造函数,此时把调用过来的Father的this 修改成了Son的this,因为是在Son里面调用的

利用原型对象继承方法

// 借用父构造函数继承属性
        // 1. 父构造函数
        function Father(uname, age) {
            // this 指向父构造函数的对象实例
            this.uname = uname;
            this.age = age;
        }
        Father.prototype.money = function() {
            console.log(100000);

        };
        // 2 .子构造函数 
        function Son(uname, age, score) {
            // this 指向子构造函数的对象实例
            Father.call(this, uname, age);
            this.score = score;
        }
        // Son.prototype = Father.prototype;  这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
        Son.prototype = new Father();
        // 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数
        Son.prototype.constructor = Son;
        // 这个是子构造函数专门的方法
        Son.prototype.exam = function() {
            console.log('孩子要考试');

        }
        var son = new Son('刘德华', 18, 100);
        console.log(son);
        console.log(Father.prototype);
        console.log(Son.prototype.constructor);

直接把父构造函数原型对象赋给子构造函数原型对象,会导致直接父构造函数也会有子构造函数的方法,所以先让父构造函数实例一下创建一个新的实例对象,实例对象的对象原型proto指向父构造函数,因此实例对象会有父构造函数的方法,再把实例对象赋给子构造函数的原型对象,子构造函数就会有父构造函数的方法,父构造函数也不会有子构造函数的方法

类的本质:

1.class本质还是function.

2.类的所有方法都定义在类的prototype属性上

3.类创建的实例,里面也有proto指向类的prototype原型对象

4.所以ES6的类它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

5.所以ES6的类其实就是语法糖.

6.语法糖:语法糖就是一种便捷写法.简单理解,有两种方法可以实现同样的功能,但是一种写法更加清晰、方便,那么这个方法就是语法糖

ES5新增的数组方法:forEach() map() filter() some() every():

forEach(): foreach和some的区别:foreach里面使用return 不能停止循环,some中遇到return就会终止(必须是true,因为some的特性就是找到返回true就会终止)

// forEach 迭代(遍历) 数组
        var arr = [1, 2, 3];
        var sum = 0;
        arr.forEach(function(value, index, array) {
            console.log('每个数组元素' + value);
            console.log('每个数组元素的索引号' + index);
            console.log('数组本身' + array);
            sum += value;
        })
        console.log(sum);

filter(): 返回一个新数组

  // filter 筛选数组
        var arr = [12, 66, 4, 88, 3, 7];
        var newArr = arr.filter(function(value, index) {
            // return value >= 20;
            return value % 2 === 0;
        });
        console.log(newArr);

some():查找数组中是否有满足条件的元素,返回的是布尔值,能查找到就返回true,查找不到返回false,能查找到满足第一个条件的元素终止循环,没查找到就继续循环

 // some 查找数组中是否有满足条件的元素 
        // var arr = [10, 30, 4];
        // var flag = arr.some(function(value) {
        //     // return value >= 20;
        //     return value < 3;
        // });
        // console.log(flag);
        var arr1 = ['red', 'pink', 'blue'];
        var flag1 = arr1.some(function(value) {
            return value == 'pink';
        });
        console.log(flag1);
        

filter 也是查找满足条件的元素 返回的是一个数组 而且是把所有满足条件的元素返回回来

some 也是查找满足条件的元素是否存在 返回的是一个布尔值 如果查找到第一个满足条件的元素就终止循环

trim():去除两端的空格 返回字符串

 // trim 方法去除字符串两侧空格
        var str = '   an  dy   ';
        console.log(str);
        var str1 = str.trim();
        console.log(str1);
        var input = document.querySelector('input');
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        btn.onclick = function() {
            var str = input.value.trim();
            if (str === '') {
                alert('请输入内容');
            } else {
                console.log(str);
                console.log(str.length);
                div.innerHTML = str;
            }
        }

对象方法:

Object.keys() 获取对象自身的所有属性

 // 用于获取对象自身所有的属性
        var obj = {
            id: 1,
            pname: '小米',
            price: 1999,
            num: 2000
        };
        var arr = Object.keys(obj);
        console.log(arr);
        arr.forEach(function(value) {
            console.log(value);

        })

Object.defineProperty() 定义对象中新属性或修改原有的属性

Object.defineProperty(obj,prop,descriptor) obj:目标对象 prop:需定义或修改的属性的名字 descriptor目标属性所拥有的特性

Object.defineProperty)第三个参数descriptor说明︰以对象形式{}书写

value:设置属性的值 默认为undefined

writable:值是否可以重写 。true | false 默认为false

enumerable:目标属性是否可以被遍历。true | false默认为false

configurable:目标属性是否可以被删除或是否可以再次修改特性true | false 默认为false

 // Object.defineProperty() 定义新属性或修改原有的属性
        var obj = {
            id: 1,
            pname: '小米',
            price: 1999
        };
        // 1. 以前的对象添加和修改属性的方式
        // obj.num = 1000;
        // obj.price = 99;
        // console.log(obj);
        // 2. Object.defineProperty() 定义新属性或修改原有的属性
        Object.defineProperty(obj, 'num', {
            value: 1000,
            enumerable: true
        });
        console.log(obj);
        Object.defineProperty(obj, 'price', {
            value: 9.9
        });
        console.log(obj);
        Object.defineProperty(obj, 'id', {
            // 如果值为false 不允许修改这个属性值 默认值也是false
            writable: false,
        });
        obj.id = 2;
        console.log(obj);
        Object.defineProperty(obj, 'address', {
            value: '中国山东蓝翔技校xx单元',
            // 如果只为false 不允许修改这个属性值 默认值也是false
            writable: false,
            // enumerable 如果值为false 则不允许遍历, 默认的值是 false
            enumerable: false,
            // configurable 如果为false 则不允许删除这个属性 不允许在修改第三个参数里面的特性 默认为false
            configurable: false
        });
        console.log(obj);
        console.log(Object.keys(obj));
        delete obj.address;
        console.log(obj);
        delete obj.pname;
        console.log(obj);
        Object.defineProperty(obj, 'address', {
            value: '中国山东蓝翔技校xx单元',
            // 如果值为false 不允许修改这个属性值 默认值也是false
            writable: true,
            // enumerable 如果值为false 则不允许遍历, 默认的值是 false
            enumerable: true,
            // configurable 如果为false 则不允许删除这个属性 默认为false
            configurable: true
        });
        console.log(obj.address);

函数进阶:

创建函数的方式:

 //  函数的定义方式

        // 1. 自定义函数(命名函数) 

        function fn() {};

        // 2. 函数表达式 (匿名函数)

        var fun = function() {};


        // 3. 利用 new Function('参数1','参数2', '函数体');

        var f = new Function('a', 'b', 'console.log(a + b)');
        f(1, 2);
        // 4. 所有函数都是 Function 的实例(对象)
        console.dir(f);
        // 5. 函数也属于对象
        console.log(f instanceof Object);  //前者等于后者吗?

调用函数方法:

 // 函数的调用方式

        // 1. 普通函数
        function fn() {
            console.log('人生的巅峰');

        }
        // fn();   fn.call()
        // 2. 对象的方法
        var o = {
            sayHi: function() {
                console.log('人生的巅峰');

            }
        }
        o.sayHi();
        // 3. 构造函数
        function Star() {};
        new Star();
        // 4. 绑定事件函数
        // btn.onclick = function() {};   // 点击了按钮就可以调用这个函数
        // 5. 定时器函数
        // setInterval(function() {}, 1000);  这个函数是定时器自动1秒钟调用一次
        // 6. 立即执行函数
        (function() {
            console.log('人生的巅峰');
        })();
        // 立即执行函数是自动调用

函数的this指向:

 // 函数的不同调用方式决定了this 的指向不同
        // 1. 普通函数 this 指向window
        function fn() {
            console.log('普通函数的this' + this);
        }
        window.fn();
        // 2. 对象的方法 this指向的是对象 o
        var o = {
            sayHi: function() {
                console.log('对象方法的this:' + this);
            }
        }
        o.sayHi();
        // 3. 构造函数 this 指向 ldh 这个实例对象 原型对象里面的this 指向的也是 ldh这个实例对象
        function Star() {};
        Star.prototype.sing = function() {

        }
        var ldh = new Star();
        // 4. 绑定事件函数 this 指向的是函数的调用者 btn这个按钮对象
        var btn = document.querySelector('button');
        btn.onclick = function() {
            console.log('绑定时间函数的this:' + this);
        };
        // 5. 定时器函数 this 指向的也是window
        window.setTimeout(function() {
            console.log('定时器的this:' + this);

        }, 1000);
        // 6. 立即执行函数 this还是指向window
        (function() {
            console.log('立即执行函数的this' + this);
        })();

Call方法及应用   特性:可以继承

 // 改变函数内this指向  js提供了三种方法  call()  apply()  bind()

        // 1. call()
        var o = {
            name: 'andy'
        }

        function fn(a, b) {
            console.log(this);
            console.log(a + b);

        };
        fn.call(o, 1, 2);
        // call 第一个可以调用函数 第二个可以改变函数内的this 指向
        // call 的主要作用可以实现继承
        function Father(uname, age, sex) {
            this.uname = uname;
            this.age = age;
            this.sex = sex;
        }

        function Son(uname, age, sex) {
            Father.call(this, uname, age, sex);
        }
        var son = new Son('刘德华', 18, '男');
        console.log(son);

apply方法及应用  特性:apply传参数必须是数组

 // 改变函数内this指向  js提供了三种方法  call()  apply()  bind()

        // 2. apply()  应用 运用的意思
        var o = {
            name: 'andy'
        };

        function fn(arr) {
            console.log(this);
            console.log(arr); // 'pink'

        };
        fn.apply(o, ['pink']);
        // 1. 也是调用函数 第二个可以改变函数内部的this指向
        // 2. 但是他的参数必须是数组(伪数组)
        // 3. apply 的主要应用 比如说我们可以利用 apply 借助于数学内置对象求数组最大值 
        // Math.max();
        var arr = [1, 66, 3, 99, 4];
        var arr1 = ['red', 'pink'];
        // var max = Math.max.apply(null, arr);
        var max = Math.max.apply(Math, arr);
        var min = Math.min.apply(Math, arr);
        console.log(max, min);

bind方法及应用  特性:不能调用函数,返回的是改变指向后的函数

<button>点击</button>
    <button>点击</button>
    <button>点击</button>
    <script>
        // 改变函数内this指向  js提供了三种方法  call()  apply()  bind()

        // 3. bind()  绑定 捆绑的意思
        var o = {
            name: 'andy'
        };

        function fn(a, b) {
            console.log(this);
            console.log(a + b);


        };
        var f = fn.bind(o, 1, 2);
        f();
        // 1. 不会调用原来的函数   可以改变原来函数内部的this 指向
        // 2. 返回的是原函数改变this之后产生的新函数
        // 3. 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向此时用bind
        // 4. 我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮
        // var btn1 = document.querySelector('button');
        // btn1.onclick = function() {
        //     this.disabled = true; // 这个this 指向的是 btn 这个按钮
        //     // var that = this;
        //     setTimeout(function() {
        //         // that.disabled = false; // 定时器函数里面的this 指向的是window
        //         this.disabled = false; // 此时定时器函数里面的this 指向的是btn
        //     }.bind(this), 3000); // 这个this 指向的是btn 这个对象
        // }
        var btns = document.querySelectorAll('button');
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                this.disabled = true;
                setTimeout(function() {
                    this.disabled = false;
                }.bind(this), 2000);
            }
        }

闭包

 // 闭包(closure)指有权访问另一个函数作用域中变量的函数。
        // 闭包: 我们fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量 num
        function fn() {
            var num = 10;

            function fun() {
                console.log(num);

            }
            fun();
        }
        fn();

在作用域被访问的就是闭包

优点:可以访问函数作用于的局部变量

            可以避免变量污染

缺点:不会被js垃圾回收机制回收,导致内存泄漏等问题

递归

// 递归函数 : 函数内部自己调用自己, 这个函数就是递归函数
        var num = 1;

        function fn() {
            console.log('我要打印6句话');

            if (num == 6) {
                return; // 递归里面必须加退出条件
            }
            num++;
            fn();
        }
        fn();

浅拷贝

拷贝地址,修改拷贝过来的属性,被拷贝的属性也会被修改

方法:for in、assign

 // 浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用.
    // 深拷贝拷贝多层, 每一级别的数据都会拷贝.
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            }
        };
        var o = {};
        // for (var k in obj) {
        //     // k 是属性名   obj[k] 属性值
        //     o[k] = obj[k];
        // }
        // console.log(o);
        // o.msg.age = 20;
        // console.log(obj);

        console.log('--------------');
        Object.assign(o, obj);//拷贝给谁  拷贝谁
        console.log(o);
        o.msg.age = 20;
        console.log(obj);

深拷贝

方法:递归函数、...

拷贝过来的复杂数据类型开辟一个新的内存 修改后不会变

// 深拷贝拷贝多层, 每一级别的数据都会拷贝.
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            },
            color: ['pink', 'red']
        };
        var o = {};
        // 封装函数 
        function deepCopy(newobj, oldobj) {
            for (var k in oldobj) {
                // 判断我们的属性值属于那种数据类型
                // 1. 获取属性值  oldobj[k]
                var item = oldobj[k];
                // 2. 判断这个值是否是数组
                if (item instanceof Array) {
                    newobj[k] = [];
                    deepCopy(newobj[k], item)
                } else if (item instanceof Object) {
                    // 3. 判断这个值是否是对象
                    newobj[k] = {};
                    deepCopy(newobj[k], item)
                } else {
                    // 4. 属于简单数据类型
                    newobj[k] = item;
                }

            }
        }
        deepCopy(o, obj);
        console.log(o);

        var arr = [];
        console.log(arr instanceof Object);
        o.msg.age = 20;
        console.log(obj);

ES6:

#### let 不存在变量提升

let 不影响作用域链  

let 不能重复声明

let存在块级作用作用域  if  else  for while

let a;
let b,c,d;
let e=100;
let f=200,g='i love u',h=[];

//1、不能重复声明
let aa=1;
let aa=2; 


//2 有块级作用域   if  else  for while
{
    let bb=1;
}
 console.log(bb)//报错 bb is not a defined


//3、不存在变量提升
console.log(lhb) //undefind   var lhb;
var lhb=22;   
let aaa=11;

//4、不影响作用域链

{
    let pp=11;
    function dudu(){
        console.log(pp)  //11
    }
    dudu();
}

const

1、存在块级作用域

2、一定要赋初始值

3、不能修改常量

4、一般常量用大写(潜规则)

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

解构赋值

1、数组的结构

let F4=['刘能','赵本山','小沈阳','宋小宝']
let [liu,zhao,xiao,song]=F4//给每个变量进行赋值
console.log(liu)//刘能
console.log(zhao)//赵本山
console.log(xiao)//小沈阳
console.log(song)//宋小宝

2、对象结构

const Zhao={
	name:'赵本山',
	age:'50',
	xiaopin:function(){
		console.log('我会演小品')
	}
}
  let {z,a,xp}=Zhao;
  	console.log(name)//赵本山
	console.log(age)//50
	console.log(xiaopin)//我会演小品
	xiaopin();

模板字符串

//1、声明
let a=`我是一个字符串哦哈哈哈`
console.log(a,typeof a)//我是一个字符串哦哈哈哈 string

//2、可以直接换行
	let st=`<ul>
				<li>123</li>
				<li>321</li>
				<li>12345</li>
			</ul>`
    
//3、变量拼接
    let as='李一诺'
    let out=`${as}是狗!` //固定写法 ${}
    console.log(out);//李一诺是狗!

箭头函数

  1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值

  2. 不能作为构造实例化对象

  3. 不能使用 arguments 变量

// ES6 允许使用「箭头」(=>)定义函数。
        //声明一个函数
        // let fn = function(){

        // }
        // let fn = (a,b) => {
        //     return a + b;
        // }
        //调用函数
        // let result = fn(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 = '尚硅谷';
        const school = {
            name: "ATGUIGU"
        }

        //直接调用
        // getName();
        // getName2();

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

        //2. 不能作为构造实例化对象
        // let Person = (name, age) => {
        //     this.name = name;
        //     this.age = age;
        // }
        // let me = new Person('xiao',30);
        // console.log(me);

        //3. 不能使用 arguments 变量
        // let fn = () => {
        //     console.log(arguments);
        // }
        // fn(1,2,3);

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

参数默认值

//ES6 允许给函数参数赋值初始值
        //1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
        // function add(a,c=10,b) {
        //     return a + b + c;
        // }
        // let result = add(1,2);
        // console.log(result);

        //2. 与解构赋值结合
        function connect({host="127.0.0.1", username,password, port}){
            console.log(host)
            console.log(username)
            console.log(password)
            console.log(port)
        }
        connect({
            host: 'atguigu.com',
            username: 'root',
            password: 'root',
            port: 3306
        })

rest参数

 // ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
        // ES5 获取实参的方式
         function date(){
             console.log(arguments);
         }
         date('白芷','阿娇','思慧');

        // rest 参数
         function date(...args){
             console.log(args);// filter some every map 
         }
         date('阿娇','柏芝','思慧');

        // rest 参数必须要放到参数最后
        function fn(a,b,...args){
             console.log(a);
             console.log(b);
             console.log(args);
         }
        // fn(1,2,3,4,5,6);

扩展运算符

有引用数据类型就是浅拷贝

 //1. 数组的合并 情圣  误杀  唐探
         const kuaizi = ['王太利','肖央'];
         const fenghuang = ['曾毅','玲花'];
         const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
         const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
         console.log(zuixuanxiaopingguo);

    //2. 数组的克隆
         const sanzhihua = ['E','G','M'];
         const sanyecao = [...sanzhihua];//  ['E','G','M']
         console.log(sanyecao);

     //3. 将伪数组转为真正的数组
        const divs = document.querySelectorAll('div');
        const divArr = [...divs];
        console.log(divArr);// arguments

对象添加symbol属性

添加的属性是具有唯一性的

//向对象中添加方法 up down
        let game = {
            name:'俄罗斯方块',
            up: function(){},
            down: function(){}
        };
        
        //声明一个对象
        // let methods = {
        //     up: Symbol(),
        //     down: Symbol()
        // };

        // game[methods.up] = function(){
        //     console.log("我可以改变形状");
        // }

        // game[methods.down] = function(){
        //     console.log("我可以快速下降!!");
        // }

        // console.log(game);

        //
        let youxi = {
            name:"狼人杀",
            [Symbol('say')]: function(){
                console.log("我可以发言")
            },
            [Symbol('zibao')]: function(){
                console.log('我可以自爆');
            }
        }

        console.log(youxi)

迭代器

自定义遍历属性,首先想到迭代器

for in返回属性名,for of 返回属性值

  //声明一个数组
        const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];

        //使用 for...of 遍历数组  
        // for(let v of xiyou){
        //     console.log(v);
        // }

        let iterator = xiyou[Symbol.iterator]();

        //调用对象的next方法
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());

Promise

 //实例化 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);
        }, function(reason){
            console.error(reason);
        })

Promise.then

//创建 promise 对象
        const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                resolve('用户数据');
                // reject('出错啦');
            }, 1000)
        });

        //调用 then 方法  then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
        //1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值

        // const result = p.then(value => {
        //     console.log(value);
        //     //1. 非 promise 类型的属性
        //     // return 'iloveyou';
        //     //2. 是 promise 对象
        //     // return new Promise((resolve, reject)=>{
        //     //     // resolve('ok');
        //     //     reject('error');
        //     // });
        //     //3. 抛出错误
        //     // throw new Error('出错啦!');
        //     throw '出错啦!';
        // }, reason=>{
        //     console.warn(reason);
        // });

        //链式调用
        p.then(value=>{

        }).then(value=>{

        });

Promise.catch

  const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                //设置 p 对象的状态为失败, 并设置失败的值
                reject("出错啦!");
            }, 1000)
        });

        // p.then(function(value){}, function(reason){
        //     console.error(reason);
        // });

        p.catch(function(reason){
            console.warn(reason);
        });

Set(集合)

set可以存任何数据

 //声明一个 set
        let s = new Set();
        let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);

        //元素个数
        // console.log(s2.size);
        //添加新的元素
        // s2.add('喜事儿');
        //删除元素
        // s2.delete('坏事儿');
        //检测
        // console.log(s2.has('糟心事'));
        //清空
        // s2.clear();
        // console.log(s2);

        for(let v of s2){
            console.log(v);
        }

Set集合实践

let arr = [1,2,3,4,5,4,3,2,1];
        //1. 数组去重
        // let result = [...new Set(arr)];
        // console.log(result);
        //2. 交集
        let arr2 = [4,5,6,5,6];
        // let result = [...new Set(arr)].filter(item => {
        //     let s2 = new Set(arr2);// 4 5 6
        //     if(s2.has(item)){
        //         return true;
        //     }else{
        //         return false;
        //     }
        // });
        // let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
        // console.log(result);

        //3. 并集
        // let union = [...new Set([...arr, ...arr2])];
        // console.log(union);

        //4. 差集
        let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
        console.log(diff);

Map

map存的是键值对

 //声明 Map
        let m = new Map();

        //添加元素
        m.set('name','尚硅谷');
        m.set('change', function(){
            console.log("我们可以改变你!!");
        });
        let key = {
            school : 'ATGUIGU'
        };
        m.set(key, ['北京','上海','深圳']);

        //size
        // console.log(m.size);

        //删除
        // m.delete('name');

        //获取
        // console.log(m.get('change'));
        // console.log(m.get(key));

        //清空
        // m.clear();

        //遍历
        for(let v of m){
            console.log(v);
        }

        // console.log(m);

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到