前端工程化15-邂逅ES6的语法规范

news2024/11/15 23:56:38

4、ES6邂逅

3.1、什么是ECMA

image-20240810191809621

ECMA(European Computer Manufacturers Association)中文名为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1

994年后该组织改名为Ecma国际。

3.2、什么是ECMAScript

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

3.3、什么是ECMA-262

Ecma国际制定了许多标准,而ECMA-262只是其中的一个,所有标准列表查看

http://www.ecma-international.org/publications/standards/Standard.htm

3.4、ECMA262历史

ECMA-262(ECMAScript)历史版本查看网址

第1版1997年制定了语言的基本语法
第2版1998年较小改动
第3版1999年引入正则、异常处理、格式化输出等。IE开始支持
第4版2007年过于激进,未发布
第5版2009年引入严格模式、JSON,扩展对象、数组、原型、字符串、日期方法
第6版2015年模块化、面向对象语法、Promise、箭头函数、let、const、数组解构赋值等等
第7版2016年幂运算符、数组扩展、Async/await关键字
第8版2017年Async/await、字符串扩展
第9版2018年对象解构赋值、正则扩展
第10版2019年扩展对象、数组方法
ES.next动态指向下一个版本

注:从ES6开始,每年发布一个版本,版本号比年份最后一位大1

3.5、谁在维护ECMA262

TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期召开会议,会议由会员公司的代表与特邀专家出席

3.6、为什么要学习ES6

ES6的版本变动内容最多,具有里程碑意义

ES6加入许多新的语法特性,编程实现更简单、高效

ES6是前端发展趋势,就业必备技能

3.8、ES6兼容性

https://compat-table.github.io/compat-table/es6/ 可查看兼容性

image-20240810192712430

3.9、ES6的Let关键字

let关键字用来声明变量,使用let声明的变量有几个特点:

  • 不允许重复声明
  • 块儿级作用域
  • 不存在变量提升

应用场景:以后声明变量使用let就对了

代码实战

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>let</title>
</head>
<body>
    <script>
        //let 声明变量
        let a;          //字母数字下划线, 首字母不能为数字, 严格区分大小写, 不能使用关键字   驼峰
        let b = 100;
        let c,d,e;
        let f=100,g=200,h=300;

        //let 声明特点
        //1. 不允许重复声明
        // let star = '罗志祥';
        // let star = '小猪';
        
        //2. 块儿级作用域  if(){}  else {}  for(){}   {}   function(){}
        // if(true){
        //     let girlFriend = '周扬青';
        // }
        // console.log(girlFriend);

        //3. 不存在变量提升
        // console.log(song);
        // let song = '狐狸精';

        //4. 不影响作用域链
        // function fn(){
        //     let dance = '精武门';
        //     function b(){
        //         console.log(dance);
        //     }
        //     b();
        // }
        // fn();
        
    </script>
</body>
</html>

3.1、let实践案例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>点击 DIV 换色</title>
    <style>
        .item {
            width: 100px;
            height: 50px;
            border: solid 1px rgb(42, 156, 156);
            float: left;
            margin-right: 10px;
        }
    </style>
</head>

<body>
    <div class="container">
        <h2 class="page-header">点击切换颜色</h2>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
    <script>
        //获取元素对象
        let items = document.querySelectorAll('.item');

        //用this实现
        // for(var i=0;i<items.length;i++){
        //     //绑定事件
        //     items[i].onclick = function(){
        //         //
        //         this.style.background = 'pink';
        //     }
        // }

        //遍历并绑定事件
        // for(let i=0;i<items.length;i++){
        //     //绑定事件
        //     items[i].onclick = function(){
        //         //
        //         items[i].style.background = 'pink';
        //     }
        // }

        // ES5 模拟实现
        for(var i=0;i<items.length;i++){
            (function(i){
                //绑定事件
                items[i].onclick = function(){
                    //
                    items[i].style.background = 'pink';
                }
            })(i)
        }
    </script>
</body>

</html>

3.4、ES6的const关键字

const 关键字用来声明常量,const声明有以下特点

  • 声明一定要赋初始值

  • 不允许重复声明

  • 值不允许修改

  • 块儿级作用域

注意:对象属性修改和数组元素变化不会出发const错误

应用场景:声明对象类型使用const,非对象类型声明选择let

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>const 定义常量</title>
</head>
<body>
    <script>
        //const 用来声明一个常量(值不变) let a
        //0. 格式
        // const a = 100;  
        //1. 声明的时候一定要赋初始值
        const PLAYER = 'UZI';
        //2. 常量的名称一般为 『大写』  潜规则
        const RESOLVED = 'resolved';
        //3. 不能修改常量的值
        // PLAYER = '小狗';
        //4. 不允许重复声明
        // const PLAYER = 'abc';
        //5. 块儿级作用域
        // {
        //     const A = 100;
        // }
        // console.log(A);
        //6. 关于数组和对象的元素的修改
        // const TEAM = ['UZI','MLXG','LETME'];
        // TEAM.push('XIYE');
        // console.log(TEAM);
        // const BIN = {
        //     name: 'BIN'
        // }
        // BIN.name = '阿斌';
        // console.log(BIN);
    </script>
</body>
</html>

3.5、ES6变量的结构赋值

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

注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>变量的解构赋值</title>
</head>
<body>
    <script>
        //解构赋值
        // const arr = ['宋小宝','刘能','赵四','小沈阳'];
        // let [song, liu, zhao, xiao] = arr;
        // console.log(song, liu, zhao, xiao);

        //对象解构赋值
        const star = {
            name: '于谦',
            tags: ['抽烟','喝酒','烫头'],
            say: function(){
                console.log('我可以说相声');
            }
        };
        let {name, tags:[chou,he,tang], say} = star;

        // console.log(name);
        // console.log(tags);
        // console.log(say);

        console.log(chou)
        console.log(he)
        console.log(tang)

        
    </script>
</body>

</html>

3.6、模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识,

特点:

  • 字符串中可以出现换行符
  • 可以使用 ${xxx} 形式输出变量
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板字符串</title>
</head>
<body>
    <script>
        //1. 直接使用换行符
        let str = `<ul>
                <li>沈腾</li>
                <li>马丽</li>
                <li>艾伦</li>
                <li>魏翔</li>
            </ul>`;
            
        //2. 字符串中进行变量拼接
        let star = '魏翔';
        let str2 = `我特别喜欢 ${star}, 搞笑风格诡异`;

        console.log(str2);
    </script>
</body>
</html>

3.7、简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

注意:对象简写形式简化了代码,所以以后用简写就对了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简化对象写法</title>
</head>
<body>
    <script>
        let name = '茂昌';
        let pos = '邯郸';
        let change = function(){
            console.log('改变');
        }
        
        //简写前
        const renOne = {
            name:name,
            pos:pos,
            change:change,
            improve:function(){
                console.log('提升');
            }
        }
        //简写后 
        const renTwo = {
            name,
            pos,
            change,
            improve(){
                console.log('提升');
            }
        }
        console.log(renOne)
        console.log(renTwo)

    </script>
</body>
</html>

3.8、箭头函数

ES6 允许使用「箭头」(=>)定义函数。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>箭头函数</title>
</head>
<body>
    <script>
        // ES6 允许使用「箭头」(=>)定义函数。
        //1. 声明格式 
        // let add = (a,b,c) => {
        //     let result = a + b + c;
        //     return result;
        // };
        //2. 函数调用
        // console.log(add(1,2,3));
        // console.log(add.call({}, 1,2,3));
        // console.log(add.apply({}, [1,2,3]));

        // 箭头函数特点 
        // 1. this 的值是静态的. (指向声明时所在作用域下this的值)
        // let getName2 = () => {
        //     console.log(this);
        // }
        // getName2.call({}); 外层作用域下的this值

        // 2. 不能作为构造函数使用
        // const Person = () => {}
        // let me = new Person();

        // 3. 不能使用 arguments 
        // const fn = () => {
        //     console.log(arguments);
        // }
        // fn(1,3,5,8,10);

        // 4. 箭头函数简写
        // 一 不写小括号, 当形参有且只有一个的时候
        // 二 不写花括号, 当代码体只有一条语句的时候, 并且语句的执行结果为函数返回值的 (如果不写花括号的话, return 也不能写)
        // let pow = num =>  num * num * num;
        let rand = (m,n) => Math.ceil(Math.random() * (n-m+1)) + m-1;

        // console.log(pow(9));
        console.log(rand(1,100));
    </script>
</body>
</html>

箭头函数的注意点:

  • 箭头函数this指向声明时所在作用域下 this 的值

  • 箭头函数不能作为构造函数实例化

  • 箭头函数内没有arguments

  • 如果形参只有一个,则小括号可以省略

  • 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果

3.9、箭头函数的最佳实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>箭头函数实践</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background: #58a;
        }
    </style>
</head>
<body>
    <div id="ad"></div>
    <script>
        //需求-1  点击 div 2s 后颜色变成「粉色」
        const ad = document.getElementById('ad');
        //绑定事件
        ad.onclick = function(){
            //保存 this 的值  that  self  _this
            // let that = this
            // setTimeout(function(){
            //     that.style.background = 'pink';
            // }, 2000);

            setTimeout(() => {
                this.style.background = 'pink';
            }, 2000)
        }

        //需求-2  从数组中返回偶数的元素
        const arr = [1,2,31,2,321,41,24,12,51,24,12,43,145,1,51,5,43,5,43,6,436];

        //遍历  filter 过滤
        // const result = arr.filter(function(item){
        //     //判断是否为偶数
        //     if(item % 2 === 0){
        //         return true;
        //     }else{
        //         return false;
        //     }
        // });

        const result = arr.filter(item => item % 2 === 0);

        console.log(result);

        //如果回调与this的值是相关的, 则不能使用箭头函数
        //1. 事件的回调
        // ad.onclick = () => {
        //     console.log(this);
        // }
        //2. 对象的方法
        // let f = () => {
        //     console.log(this);
        // };
        // var obj = {
        //     run: function(){
        //         console.log(this);
        //     },
        //     run2: f
        // }
        // // obj.run();
        // obj.run2();

        //如果回调与 this 是无关的
        //1. 定时器
        //2. 数组方法回调  filter  forEach  map

    </script>
</body>

</html>

3.1、函数参数默认值

注意: 参数直接设置默认值 具有默认值的参数, 位置一般要靠后(潜规则)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>函数参数默认值</title>
</head>
<body>
    <script>
        //ES6 允许给函数参数赋值初始值
        //1. 参数直接设置默认值  具有默认值的参数, 位置一般要靠后(潜规则)  ---很重要
        function add(a,b=10,c){
            console.log(a + b + c);
        }
        // add(1,2,4);
        // add(1,2);

        //2. 与解构赋值结合使用   结构赋值的形式先后顺序不影响
        function connect({host="127.0.0.1", port, pass, dbname}){
            console.log(host);
            console.log(port);
            console.log(pass);
            console.log(dbname);
        }

        connect({
            port: 27017,
            pass: 'root',
            dbname: 'project'
        });
        
    </script>
</body>
</html>

3.2、rest参数

主要是用来替代arguments获取实参的

注意事项,出现a,b,…args写到最后,

什么时候用rest参数:出现不定个数参数的函数比如求最大值最小值,你也不知道传递多少个参数进来,那我们就用rest参数来接收

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>rest参数</title>
</head>
<body>
    <script>
        //arguments
        function main(...args){
            //1. 使用 arguments 获取实参
            console.log(arguments); //对象
            //2. rest 参数
            console.log(args); //数组
        }
        main(1,5,10,20,25);// 1,5,10,20,25  => ...[1,5,10,20,25] => 1,5,10,20,25

        //2. 如果有多个参数,rest参数必须放到最后
        // function fn(a,b,...args){
        //     console.log(a);
        //     console.log(b);
        //     console.log(args);
        // }
        // fn(1,2,3,4,5,6,7);
    </script>
</body>
</html>

3.3、spread扩展运算符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扩展运算符 ****</title>
</head>
<body>
    <script>
        //数组的展开  
        const arr = ['王源','易烊千玺','王俊凯'];
        function fn(){
            console.log(arguments);
        }
        fn(...arr);// ...arr  => ...['王源','易烊千玺','王俊凯']  =>  '王源','易烊千玺','王俊凯'
        //fn('王源','易烊千玺','王俊凯');

        //对象的展开   ...skillOne =>  q:'天音波'
        // const skillOne = {
        //     q: '天音波',
        //     f:'闪现'
        // };
        // const skillTwo = {
        //     w: '金钟罩'
        // };
        // const skillThree = {
        //     e: '天雷破'
        // };
        // const skillFour = {
        //     r: '猛龙摆尾',
        //     q: 'xxx'
        // };
        
        //把对象的属性加入到一个新对象中    
        //const mangseng = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};

       // console.log(mangseng);
        
    </script>
    
</body>
</html>

3.4、spread扩展运算符应用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扩展运算符应用</title>
</head>
<body>
    <div></div>
    <div></div>
    <div></div>
    <script>
        //1. 数组的合并 
        // const kuaizi = ['肖央','王太利'];
        // const chuanqi = ['曾毅','玲花'];
        // const zuhe = [...kuaizi, ...chuanqi];
        // console.log(zuhe);
        //2. 新数组克隆
        // const jinhua = ['e','g','m'];//
        // const s = [...jinhua,'x','y','z'];
        // console.log(s);
        //3. 将伪数组转为真正的数组
        const divs = document.querySelectorAll('div');
        //
        const result = [...divs];

        console.log(result);
    </script>
</body>
</html>

3.5、symbol

ES6中的数据类型总共有七中

1、boolean(布尔型)2、null(空类型)3、undefined(未赋值类型)

4、number(数值类型)5、string(字符串类型)6、symbol(独一无二类型)7、object(对象类型)。

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

Symbol特点

  • Symbol的值是唯一的,用来解决命名冲突的问题
  • Symbol值不能与其他数据进行运算
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>symbol</title>
</head>
<body>
    <script>
        //ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值
        
        //1. 创建 Symbol
        let s1 = Symbol();
        console.log(s1, typeof s1);
        //2. 创建 Symbol
        // let s2 = Symbol('品牌');
        // let s3 = Symbol('品牌');
        // console.log(s2 === s3);
        //3. 创建 Symbol ----函数对象
        let s4 = Symbol.for('200826');
        let s5 = Symbol.for('200826');
        console.log(s4 === s5);

       // symbol 不能与其他类型数据进行运算
        // const result = s1 + 123;

    </script>
</body>
</html> 

3.6、symbol的使用场景

注意:Symbol类型唯一合理的用法是用变量存储 symbol的值,然后使用存储的值创建对象属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Symbol 创建对象属性</title>
</head>
<body>
    <script>
        //向对象中添加方法 up down 
        let method = {
            up: Symbol(),
            down: Symbol()
        }
        let str = 'run';

        //未知的对象,直接添加方法会有风险,因为可能已经存在了对应的方法
        //直接添加会造成属性的冲突和覆盖
        let game = {
            name:'俄罗斯方块' ,
            up: function(){

            },
            //内部添加方法
            [str]: function(){
                
            },
            //内部添加方法用up
            [method.up]: function(){
                console.log('UP UP UP');
            }
        };

        // console.log(game);
        game[method.up]();

        

        //添加 up 方法
        // game[method.up] = function(){
        //     console.log('向上移动');
        // }
        // game[method.up]();

    </script>
</body>
</html>

3.7、Symbol内置属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Symbol内置属性</title>
</head>
<body>
    <script>
        // Symbol.replace
        let obj = {
            [Symbol.replace]: function(){
                console.log('我被replace方法调用了');
            }
        }
        //声明字符串
        let str = 'i love you';
        //调用 replace 方法
        let result = str.replace(obj, 'xxx');
    </script>
</body>
</html>

被动调用的、我没有进行手动的触发

Symbol.hasInstance当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
Symbol. unscopables该对象指定了使用with关键字时,哪些属性会被with环境排除。
Symbol.match当执行str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。
Symbol.replace当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值。
Symbol.search当该对象被str. search (myObject)方法调用时,会返回该方法的返回值。
Symbol.split当该对象被str. split (myObject)方法调用时,会返回该方法的返回值。
Symbol.iterator对象进行for…of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
Symbol. toStringTag在该对象上面调用toString方法时,返回该方法的返回值
Symbol.species创建衍生对象时,会使用该属性

3.8、迭代器

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

  • ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费
  • 原生具备iterator接口的数据(可用for of遍历)
    • Array
    • Arguments
    • Set
    • Map
    • String
    • TypedArray
    • NodeList
  • 工作原理
    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
    • 每调用next方法返回一个包含value和done属性的对象

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

ctrl+shift+i 打开控制台

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>迭代器</title>
</head>
<body>
    <script>
        const arr = ['刘德华','黎明','郭富城','张学友'];

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

        //得到 iterator     
        const iterator = arr[Symbol.iterator]();

        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());

        // {value: '', done: true}

        // for(let i in arr){
        //     console.log(i);
        // }
        
    </script>
</body>
</html>

for of 和for in的区别 前置拿到的是值,后者拿到的是下标

3.9、迭代器自定义遍历数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自定义遍历数据</title>
</head>
<body>
    <script>
        const team = {
            name: '终极一班',
            members: [
                'xiaoming',
                'xiaoning',
                'xiaotian',
                'knight'
            ],
            //添加 Symbol.iterator
            [Symbol.iterator]: function(){
                let index = 0;
                return {
                    next: () => {
                        //声明对象
                        const result = {value: this.members[index], done: false};
                        //判断下标 修改 『done』 属性的值
                        if(index >= this.members.length){
                            result.done = true;
                        }
                        //下标自增
                        index++;
                        //返回结果
                        return result;
                    }
                }
            }
        }
        
        //需求
        for(let v of team){
            console.log(v);
        }

        //可以
        for(let v of team.members){}

        //可以--为啥要费劲的去实现这个需求  -->面向对象编程思想--满足
        team.members.forEach();
        
    </script>
</body>

</html>

4.1、set集合

ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,可以使用『扩展运算符』和『for…of…』进行遍历,

集合的属性和方法:

  • size 返回集合的元素个数
  • add 增加一个新元素,返回当前集合
  • delete 删除元素,返回boolean 值
  • has 检测集合中是否包含某个元素,返回boolean值
  • clear 清空集合,返回undefined
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>集合</title>
</head>
<body>
    <script>
        //声明集合
        // const s = new Set();
        const s2 = new Set([1,5,9,13,17,1,5]);

        //1. 元素个数
        // console.log(s2.size);
        //2. 添加
        // s2.add(21);
        //3. 删除
        // s2.delete(5);
        //4. 检测集合中是否包含某个元素  has  有
        // console.log(s2.has(90));
        //5. clear 清空
        // s2.clear();

        // console.log(s2);
        //6. for...of 遍历
        // for(let v of s2){
        //     console.log(v);
        // }
    </script>
</body>
</html>

4.2、set集合实战

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实践</title>
</head>
<body>
    <script>
        //1. 数组去重  
        const arr = ['大事儿','小事儿','好事儿','坏事儿','小事儿'];
        //集合
        // const s = new Set(arr);
        // const result = [...s];
        // console.log(result);

        //2. 交集
        const arr1 = [1,2,3,4,5,1,2];
        const arr2 = [3,4,5,4,5,6];

        // const result = [...new Set(arr1)].filter(item => {
        //     return (new Set(arr2)).has(item);
        // });
        // console.log(result);

        //3. 并集
        // const result = [...new Set([...new Set(arr1),...new Set(arr2)])];

        //4. 差集
        const result = [...new Set(arr1)].filter(item => {
            return !(new Set(arr2)).has(item);
        });
        console.log(result);

    </script>
</body>
</html>

4.3、Map集合

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。

Map的属性和方法:

  • size 返回Map的元素个数
  • set 增加一个新元素,返回当前Map
  • get 返回键名对象的键值
  • has 检测Map中是否包含某个元素,返回boolean值
  • clear 清空集合,返回undefined
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Map</title>
</head>
<body>
    <script>
        //缓存--->比如搜索栏存第一次的推荐搜索数据
        //声明 Map    m.name = 'xiaohua';
        const m = new Map();
        //添加元素
        let key = {};
        m.set('mei', '小橙子');
        m.set(key, 'atguigu');
        //获取元素
        // console.log(m.get('mei'));
        // console.log(m.get(key));
        //删除元素
        // m.delete('mei');
        //检测
        // console.log(m.has('meix'));
        //元素个数
        // console.log(m.size);
        //清空
        // m.clear();
        // console.log(m);
    </script>
</body>
</html>

4.4、class介绍与类创建

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>对象声明</title>
</head>
<body>
    <script>
        //创建对象的方式 new Object  {}  工厂函数  构造函数  Object.create
        // function Phone(brand, price){
        //     this.brand = brand;
        //     this.price = price;
        // }
        // //添加方法
        // Phone.prototype.call = function(someone){
        //     console.log(`我可以给 ${someone} 打电话`);
        // }
        // Phone.prototype.sendMessage = function(someone){
        //     console.log(`我可以给 ${someone} 发送短信`);
        // }

        // //实例化对象
        // const nokia = new Phone('诺基亚', 223);

        //语法
        class Phone {
            //构造方法--名字必须为这个
            constructor(brand, price){
                this.brand = brand;
                this.price = price;
            }
            //方法
            call(someone){
                console.log(`我可以给 ${someone} 打电话`);
            }
            sendMessage(someone){
                console.log(`我可以给 ${someone} 发送短信`);
            }
        }

        const jinli = new Phone('金立', 599);
        console.log(jinli);


        
        //1.构造方法不是必须的
        class A{
            //2. 构造方法只能有一个
            constructor(){}
            constructor(){}
        }

        let a = new A();

        console.log(a);

    </script>
</body>
</html>

4.5、对象的静态属性和方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>静态成员</title>
</head>
<body>
    <script>
        //
        // function Phone(brand){
        //     //为实例对象添加属性
        //     this.brand = brand;
        // }
        // //为函数对象添加属性
        // Phone.name = '手机';//又称之为 静态成员
        // Phone.change = function(){
        //     console.log('改变了世界');
        // }
        // //
        // let nokia = new Phone('诺基亚');
        // console.log(nokia);
        // console.dir(Phone);

        class Phone{
            //static 静态的
            static name = '手机';
            static change(){
                console.log("我改变了世界");
            }
        }

        console.log(Phone.name);
        Phone.change();

    </script>
</body>
</html>

4.6、ES5中如何实现继承

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>对象继承</title>
</head>
<body>
    <script>
        //父类
        function Phone(brand, price){
            this.brand = brand;
            this.price = price;
        }
        //添加原型方法
        Phone.prototype.call = function(someone){
            console.log(`我可以给 ${someone} 打电话`);
        }
        //添加原型方法
        Phone.prototype.sendMessage = function(someone){
            console.log(`我可以给 ${someone} 发送短信`);
        }

        //小手机
        function SmartPhone(brand, price, storage, pixel){
            //调用父类的函数  属性的初始化
            Phone.call(this, brand, price);
            //初始化
            this.storage = storage;
            this.pixel = pixel;
        }
        //子类的prototype应该等于父类的示例
        SmartPhone.prototype = new Phone;
        //添加子类自己的构造方法
        SmartPhone.prototype.constructor = SmartPhone;
        //添加子类特有的方法
        SmartPhone.prototype.playGame = function(){
            console.log('我可以用来玩游戏');
        }
        SmartPhone.prototype.takePhoto = function(){
            console.log('可以拍照');
        }
        //实例化
        const mate4 = new SmartPhone('华为', 7000, '256G','2000w');
        console.log(mate4);



    </script>
</body>
</html>

4.7、ES6实现对象继承

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>对象继承</title>
</head>
<body>
    <script>
        class Phone {
            //构造方法
            constructor(brand, price){
                this.brand = brand;
                this.price = price;
            }
            //方法
            call(someone){
                console.log(`我可以给 ${someone} 打电话`);
            }
            sendMessage(someone){
                console.log(`我可以给 ${someone} 发送短信`);
            }
        }

        //子类  extends 继承  多态
        class SmartPhone extends Phone{
            //构造方法
            constructor(brand, price, storage, pixel){
                //调用父类的构造方法 属性初始化
                super(brand, price);//super 超级
                this.storage = storage;
                this.pixel = pixel;
            }
            //子类对象的方法
            playGame(){
                console.log('我可以用来玩游戏');
            }
            takePhoto(){
                console.log('可以拍照');
            }
        }

        //实例化对象
        const onePlus = new SmartPhone('小米10', 4299, '128G','一个亿');

        console.log(onePlus);
        // onePlus.call('孙俪');
    
    </script>
</body>
</html>

4.8、ES6对象的get 和 set方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>get 和 set </title>
</head>
<body>
    <script>
        class Phone{
            get price(){
                // console.log('我被获取了');
                return 2999;
            }

            set price(v){
                this.jiage = v;
            }   

            static get size(){
                return '5.5inch';
            }

            static set size(value){
                this.chicun = value;
            }

        }
        let chuizi = new Phone();
        //属性的获取
        // console.log(chuizi.price);
        //属性的设置
        // chuizi.price = 1599;
        //属性的获取
        // let res = Phone.size;
        // console.log(res);
        //静态属性的设置
        Phone.size = '6inch';
        console.dir(Phone);

    </script>
</body>
</html>

4.9、ES6的数值扩展

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数值扩展</title>
</head>
<body>
    <script>
        //1. 二进制和八进制    4 (16)  8(256)   16(65536)
        // let n = 0b1111;// 
        // let n2 = 0o666;
        // let n3 = 1024;// 顶  赞
        // let n4 = 0xff;
        // console.log(n4);

        //2. Number.isFinite  检测一个数值是否为有限数
        // console.log(Number.isFinite(10));
        // console.log(Number.isFinite(Math.PI));
        // console.log(Number.isFinite(1/0));
        
        //3. Number.isNaN 检测一个数值是否为 NaN  isNaN
        // console.log(Number.isNaN(NaN));

        //4. Number.parseInt 字符串转整数 
        // console.log(Number.parseInt('5211314love'));
        // console.log(Number('5211314love'));

        //5. Math.trunc 将数字的小数部分抹掉 
        // console.log(Math.trunc(3.1415926));

        //6. Number.isInteger 判断一个数是否为整数 is 是否 integer 整型
        // console.log(Number.isInteger(3.2));
        // console.log(Number.isInteger(3));

        //7. 幂运算  (ES7)    Math.pow()
        console.log(3 ** 10);

    </script>
</body>
</html>

4.1、ES6的对象拓展

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>对象扩展</title>
</head>
<body>
    <script>
        //1. 判断两个值是否完全相等  ===  Object.is
        // let n = 100;
        // let n2 = 200;
        // console.log(Object.is(n, n2));
        // console.log(Object.is(NaN, NaN));// NaN === NaN

        //2. Object.assign 对象的合并
        // const A = {
        //     name: 'lsy'
        // }

        // const B = {
        //     pos: ["北京",'上海','深圳'],
        //     name: '后茂昌'
        // }

        // const C = {
        //     name: 'hmc'
        // }

        // const res = Object.assign(A, B, C);
        // console.log(res === A);
        // console.log(A);

        //3. 直接修改 __proto__ 设置原型
        // const A = {
        //     name: '父级'
        // }
        // const B = {
        //     test: '测试'
        // }
        // B.__proto__ = A;

        // console.log(B);
       
    </script>
</body>
</html>

4.2、ES6数据的浅拷贝

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>浅拷贝</title>
</head>
<body>
    <script>
        //拷贝 就是 复制   对象和数组
        //1. 直接复制
        // let arr = [1,2,3,4];
        // const newArr = arr;
        // //测试
        // newArr[0] = 521;
        // console.log(arr);
        // console.log(newArr);
        //2. 数组  
            let arr = [{name:'atguigu'},2,3,4];
            // 1> concat
            // let newArr = [].concat(arr);
            // newArr[0].name = '尚硅谷';
            // console.log(arr)
            // console.log(newArr)
            // 2> slice 
            // let newArr = arr.slice(0);
            // newArr[0].name = '尚硅谷';
            // console.log(arr)
            // console.log(newArr)
            // 3> 扩展运算符
            // let newArr = [...arr];
            // newArr[0].name = '尚硅谷';
            // console.log(arr)
            // console.log(newArr)
        //3. 对象
            //使用 assign 方法创建对象 (assign 对象的合并)
            const school = {
                name: "尚硅谷",
                pos: ['北京','上海','深圳']
            }

            const newSchool = Object.assign({}, school);

            // newSchool.name = 'atguigu';
            newSchool.pos[0] = 'beijing';

            console.log(school);
            console.log(newSchool);
    </script>
</body>
</html>

4.3、深拷贝-JSON

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深拷贝-JSON</title>
</head>
<body>
    <script>
        //JSON 实现深拷贝
        // * stringify 将 JS 对象转化为 JSON 格式的字符串
        // * parse    将 JSON 格式的字符串转化为 JS 对象
        //缺陷: 不能复制方法
        const school = {
            name: '朱岗子',
            pos: ['北京','上海','深圳'],
            founder: {
                name: 'lsy'
            },
            change: function(){
                console.log('改变');
            }
        }

        //将 对象转为 JSON 格式的字符串
        let str = JSON.stringify(school);
        //将对象转为JS对象
        let newSchool = JSON.parse(str);

        //测试
        newSchool.pos[0] = 'beijing';

        console.log(school);
        console.log(newSchool);
        // console.log(str);
        // console.log(typeof str);



    </script>
</body>

</html>

4.4、递归深拷贝的原理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>递归实现深拷贝 - 思路</title>
</head>
<body>
    <script>    
        const school = {
            name: '尚硅谷',
            pos: ['北京','上海','深圳'],
            founder: 
            {
                name: '刚哥'
            },
            change: function(){
                console.log('改变');
            }
        }

        //创建数据容器
        const newSchool = {};
        //name
        newSchool.name = school.name;
        //pos
        newSchool.pos = school.pos;
        newSchool.pos = [];
        newSchool.pos[0] = school.pos[0];
        newSchool.pos[1] = school.pos[1];
        newSchool.pos[2] = school.pos[2];
        //founder
        newSchool.founder = {};
        newSchool.founder.name = school.founder.name;
        //方法
        newSchool.change = school.change.bind(newSchool);

        newSchool.pos[0] = 'beijing';

        console.log(school);
        console.log(newSchool);

    </script>
</body>
</html>

4.5、封装实现递归深拷贝

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>递归深拷贝实现</title>
</head>
<body>
    <script>
        //封装一个函数
        function deepClone(data){
            //创建一个容器  typeof
            // console.log(typeof data);
            let container;
            //判断
            let type = getDataType(data);// Object Array
            if(type === 'Object'){
                container = {};
            }
            if(type === 'Array'){
                container = [];
            }
            //遍历数据  for...in
            for(let i in data){
                //获取键值的类型
                let type = getDataType(data[i]);// Array
                //判断
                if(type === 'Array' || type==='Object'){
                    //????  递归调用 deepClone 即可
                    container[i] = deepClone(data[i]);
                }else{
                    //如果键值为非引用类型数据  则『直接复制』
                    container[i] = data[i];
                }
            }
            //container
            return container;
        }
        
        //待克隆的数据
        const school = {
            name: '尚硅谷',
            pos: ['北京','上海','深圳'],
            founder: {
                name: '刚哥'
            },
            change: function(){
                console.log('改变');
            }
        }
        //调用函数完成深拷贝
        const newSchool = deepClone(school);

        newSchool.pos[0] = 'beijing';
        console.log(school);
        console.log(newSchool);



        //封装一个函数 用来获取数据的类型
        function getDataType(data){
            return Object.prototype.toString.call(data).slice(8, -1);
        }

        
    </script>
</body>
</html>

4.6、ES11的可选链操作符号

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>可选链操作符</title>
</head>
<body>
    <script>
      //?.
      function main(config){
       // const dbHost=config&&config.db&&config.db.host;

        const dbHost=config?.db?.host; //避免做层层判断
        console.log(dbHost);
      }
   
      main({
            db:{
                host:'127.0.0.1',
                username:"root"
            },
            caches:{
                host:'127.0.0.1',
                username:"admin"
            }  
        }
      )
    </script>
</body>
</html>

世之奇伟瑰丽,非常之观,常在于险远,只有难才能不断突破进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎样找回U盘里误删的文件?试试这些方法!

在日常工作和生活中&#xff0c;我们经常会使用U盘来存储和传输重要的文件。然而&#xff0c;由于操作失误或其他原因&#xff0c;我们有时会误删U盘中的文件。当遇到这种情况时&#xff0c;很多人可能会感到焦虑和无助。不过&#xff0c;幸运的是&#xff0c;有几种方法可以帮…

三十六、【人工智能】【机器学习】【监督学习】- Bagging算法模型

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…

【清空大脑】

清空大脑&#xff0c;就是把大脑里的想法&#xff0c;都写下来&#xff0c;放到一个地方。这样&#xff0c;可以降低大脑的压力。 我记得我第一次清空大脑的时候&#xff0c;使用的事微软OutLook的便签功能&#xff0c;一共记录了200多项。 看着这200多项&#xff0c;我感觉自…

ubuntu设置开机自动执行脚本、ubuntu设置开机自动启动java服务

使用 crontab 编辑器添加一个任务&#xff0c;该任务将在系统启动时执行你的脚本。在终端中运行以下命令&#xff1a; crontab -e添加开机自启任务&#xff1a; 在打开的编辑器中&#xff0c;添加以下行&#xff1a; reboot /home/demo.jar &这行代码告诉 cron 在每次系统…

微调神器LLaMA-Factory官方保姆级教程来了,从环境搭建到模型训练评估全覆盖

1. 项目背景 开源大模型如LLaMA&#xff0c;Qwen&#xff0c;Baichuan等主要都是使用通用数据进行训练而来&#xff0c;其对于不同下游的使用场景和垂直领域的效果有待进一步提升&#xff0c;衍生出了微调训练相关的需求&#xff0c;包含预训练&#xff08;pt&#xff09;&…

探索AI角色扮演的新前端工具:SillyTavern

在人工智能&#xff08;AI&#xff09;领域&#xff0c;角色扮演&#xff08;Roleplay&#xff09;无疑是一个富有趣味且充满潜力的应用场景。无论你是AI爱好者还是开发者&#xff0c;找到一个合适的前端工具来访问并与语言模型进行互动是至关重要的。今天&#xff0c;我们将介…

[2024_08_12日志]ONNX Runtime的使用

问题&#xff1a;Segmentation 错误。在 C API 上使用自定义 onnx 模型运行。模型在 Python 上按预期工作&#xff0c;但在 C API 上运行相同的模型时&#xff0c;会收到一个分段错误 python的模型代码如下&#xff1a; class Facenet(nn.Module):def __init__(self, backbone…

lvs详解及实例配置

目录 1.什么是负载均衡 1.1为什么用负载均衡 1.2.负载均衡类型 1.2.1.四层负载均衡 1.2.2.七层负载均衡 1.3 四层和七层的区别 2.LVS介绍 2.1LVS 的优势与不足 2.2LVS 核心组件和专业术语 3.ipvsadm命令 4.LVS集群中的增删改 4.1.管理集群服务中的增删改 4.2.管理集…

C:每日一题:单身狗

​​​​ 一、题目&#xff1a; 在一个整型数组中&#xff0c;只有一个数字出现一次&#xff0c;其他数组都是成对出现的&#xff0c;请找出那个只出现一次的数字。 整型数组 int arr[ ] {1,1,2,2,3,4,4} 二、思路分析&#xff1a; 1.&#xff0c;明确目标&#xff0c;选择…

【linux】nvidia AGX orin 多方法开机自启 .sh 文件

背景&#xff1a; 安装搜狗输入法时候&#xff0c;发现etc/xdg/autostart路径下写desktop文件的方式&#xff0c;于是把所有方案整理一下 为了让 .sh 文件在用户登录时自动执行&#xff0c;可以采用如下多种方法。 1. 使用 .desktop 文件 创建一个 .desktop 文件&#xff0c;将…

链表的奇偶节点重新排列及空指针问题分析【链表、空指针】

在处理链表问题时&#xff0c;重组链表节点是一种常见需求。本文将详细探讨如何在链表中将奇数索引节点放在偶数索引节点之前&#xff0c;并深入分析实现过程中的空指针问题及其解决方案。 1. 问题描述 给定一个单链表&#xff0c;要求将链表中的节点按照奇数索引节点在前、偶…

掌握 PyTorch 张量乘法:八个关键函数与应用场景对比解析

PyTorch提供了几种张量乘法的方法&#xff0c;每种方法都是不同的&#xff0c;并且有不同的应用。我们来详细介绍每个方法&#xff0c;并且详细解释这些函数有什么区别&#xff1a; 1、torch.matmul torch.matmul 是 PyTorch 中用于矩阵乘法的函数。它能够处理各种不同维度的张…

HTML零基础自学笔记(下)篇一 -8.8

HTML零基础自学笔记&#xff08;下&#xff09;---之表格标签详解 参考&#xff1a;pink老师篇一、表格标签是什么&#xff1f;基础内容&#xff08;主要作用、基本语法、标签释义、属性&#xff09;主要作用基本语法标签释义表格结构标签属性 合并单元格代码练习代码运行效果&…

IDEA 报错,无效的源发行版 无效的目标发行版:22

报错内容&#xff1a; 在编译项目的时候出现报错&#xff1a; 解决办法&#xff1a; 无效的源发行版 原因&#xff1a;编译的JDK版本与发布版本不一致 File -> Project Structure ->Project Settings 让其中的三处版本保持一致&#xff0c;具体操作如下&#xff1a; …

Vue3+Element-plus+setup使用vuemap/vue-amap实现高德地图API相关操作

首先要下载依赖并且引入 npm安装 // 安装核心库 npm install vuemap/vue-amap --save// 安装loca库 npm install vuemap/vue-amap-loca --save// 安装扩展库 npm install vuemap/vue-amap-extra --save cdn <script src"https://cdn.jsdelivr.net/npm/vuemap/vue-a…

linux反向代理原理:帮助用户更好地优化网络架构

Linux反向代理原理详解 反向代理是一种在网络架构中常用的技术&#xff0c;尤其在Linux环境下被广泛应用。它可以帮助实现负载均衡、安全防护和请求缓存等功能。本文将深入探讨Linux反向代理的原理、工作机制以及其应用场景。 1. 什么是反向代理 反向代理是指代理服务器接收客…

HarmonyOS Developer之图片帧动画播放器

创建image-animator组件 在pages/index目录下的hml文件中创建一个image-animator组件&#xff0c;css文件中编写组件样式&#xff0c;js文件中引用图片。 设置image-animator组件属性 添加iteration&#xff08;播放次数&#xff09;、reverse&#xff08;播放顺序&#xf…

SSM宠物商城-计算机毕业设计源码23666

摘 要 近年来&#xff0c;社会的发展和进步以及人们生活水平的提高&#xff0c;人们饲养宠物的习惯也越来越重视。很多家庭都把宠物视为家庭的重要成员。宠物不仅能给自己作伴&#xff0c;而且在生活中能充当自己精神的支柱&#xff0c;缓解压力、放松心态的伙伴。宠物不同于一…

Koa商城项目-轮播图模块(前端)

前言 通过这次独自做前后端发现有很多需要提升的地方&#xff0c;很多细节处理不到位。下面简单看一下本人自己做的效果吧~~ Git地址 https://gitee.com/ah-ah-bao/koa_system 效果图 前端代码 api/banner.ts import request from "../utils/request";export con…

Mapreduce_wordcount自定义单词计数

自定义的wordcount 数据处理过程 加载jar包 查看后面的pom文件 以上为需要的jar包路径&#xff0c;将其导入至idea中 Map package com.hadoop;import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; im…