JS - 基础 - ES6学习笔记

本文深入探讨ES6的多项新特性,包括const变量声明、let与const的选择、箭头函数的使用、模板字符串的便捷性、解构赋值的灵活性、for...of循环的高效性、Array.from与Array.of的区别、标签中的字符串拼接技巧以及ES6模块化的实践。通过实例解析,帮助读者掌握ES6的高级应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、基础语法

1. const理解

当const是对象时,指向的时地址值,所以对象不可以改变但是,对象的属性时可以改变的

2. var,let,const如何选择
  1. var函数作用域,let、const块级作用域
  2. 默认使用const,如果变量需要重新赋值或更新使用let,尽量不使用var
3. 箭头函数理解
  1. 箭头函数 - 结构
<script>
  const numbers  = [1,2,3,4,11,22,44];

  //常规方法
  const exampleA = numbers.map(function (number) {
    return number*2;
  })

  //常规箭头函数: (对象) => {}
  const exampleB = numbers.map( (number) => {
    return number*2;
  })

  //有索引的箭头函数: (对象,index) => {}
  const exampleC = numbers.map( (number,index) => {
    return `${index} + ${number*2}`;
  })

  //简写的箭头函数: 对象 => {}
  const exampleD = numbers.map( number => {
    return number*2;
  })

  //箭头函数的隐式返回,去掉return和大括号 !!!!!!!!!
  const exampleF = numbers.map( number => number*2);
  
  //没有对象时的箭头函数,要保留括号
  const exampleE = numbers.map( () => {
    return "没有时箭头函数的前面的括号是要保留的";
  });

  //命名函数
  function  getNameA(name) {
    alert(name);
  }
  getNameA("小明")

  //匿名函数
  const getNameB = name => {alert(`${name}`)};
  getNameB("小王");
  
</script>
  1. 箭头函数 - this; 箭头函数的this值指向的时父级作用域,而其他函数调用后this指向的时window
<script>
 const mingming = {
   name:'小明',
   hobbies:['Coding','Sleeping','Reading'],
   printHobbies:function () {
     console.log(this);//这里的this指向的是mingming这个对象
     this.hobbies.map(function (hobby) {
       console.log(this);//这里的this经过回调函数map后其实已经重新指向window,所以不在是mingming这个对象
       console.log(`${this.name} loves ${hobby}`)//所以name没有值,有值也是window的name值!!!
     })
   }
 };
 mingming.printHobbies();

 console.log("-------------------------------");

 const tiantian = {
   name:'天天',
   hobbies:['Coding','Sleeping','Reading'],
   printHobbies:function () {
     console.log(this);//这里的this指向的是mingming这个对象
     this.hobbies.map( (hobby) => {
       console.log(this);//使用箭头函数这时这个this就指向的时父级作用域对象
       console.log(`${this.name} loves ${hobby}`)
     })
   }
 };
 tiantian.printHobbies();
</script>
4. 模板字符串
  1. reduce函数 - 用于高亮显示 --> 不太理解
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>标签模板字符串 - 高亮</title>
</head>
<style>
    .hl{
        background-color: skyblue;
        color: white;
    }
</style>
<body>
</body>
<script>
    const title = "小明";
    const content = "学习";
    const cc = "哈哈哈哈";
    function highLight(strings,...values) {
        let newValues = values.map( value => `<span class="hl">${value}</span>`)
        return strings.reduce((prev, curr,index) => `${prev}${curr}${newValues[index]||''}`,'' )
    }
    const end = highLight`${title} 喜欢 ${content} 啊啊啊啊 唧唧歪歪 ${cc}`;
    document.body.innerHTML = end;
</script>
</html>
  1. 方便的编写html代码,可以内部嵌套反引号模板标签``
<script>
    const names = ['小明','小王','小张'];
    const namesLabel = `
         <ul>
           ${names.map( name => `<li> ${name} </li>`).join('')} //.join('') --> 去掉数组循环时候的逗号“,”!
        </ul>
    `;
    document.body.innerHTML = namesLabel;
    //输出
    //       <ul>
    //              <li> 小明 </li><li> 小王 </li><li> 小张 </li>
    //       </ul>
</script>
  1. 引入方法,可以用来过滤XSS攻击
<script>
    const names = ['小明','小王','小张'];
    
    function getNames(names) {
         let data = `
                    <ul>
                        ${names.map( name => `<li> ${name}</li>`).join('')}
                    </ul>
                    `;
        return data;
    }
    
    const namesLabel = `
        <div>
                其他标签
        </div>
                ${getNames(names)} //使用函数方法
        <div>
                其他标签
        </div>
            `;
    document.body.innerHTML = namesLabel;
</script>
5. 方法形参默认值,注意只有undefined的时候才有效,null无效
	function haha(a=5,b=10){return a*n)
	//haha(2,3) --> 6;
	//haha(1) --> 1 * 默认值10 --> 10;
	//haha(undefined,1) --> 默认值5 * 1 --> 5;
6. 字符串方法startsWith(),endsWith(),includes(),repeat()

startsWith(判断值,从当前字符串第几个字符的索引值开始可不传即0开始)
includes包含可替代indexof
repeat重复执行当前字符串几次,可用于对其

7. 解构赋值

对象解构 const {}
数组解构 const []

  1. 对象
<script>
    const xiaoming = {
        name:'小明',
        age:18,
        todos:{
            1:'哈哈',
            2:'喜喜',
            3:'呵呵'
        }
    };
    const todos = xiaoming.todos;
    console.log(todos)//获取对象中的一堆属性
    console.log("--------------------------------------------------");

    const {name:myname,age:myage,sex='男'} = xiaoming;
    console.log(myname);//当属性变量名与结构名一致的时候直接写,不然中间就用冒号:引用
    console.log(myage);//当属性变量名与结构名一致的时候直接写,不然中间就用冒号:引用
    console.log(sex);//当对象中没有时,可以用等号设置默认值
    console.log("--------------------------------------------------");

    const {name,age} = xiaoming;
    console.log(name);//当属性变量名与结构名一致的时候直接写,不然中间就用冒号:引用
    console.log(age);//当属性变量名与结构名一致的时候直接写,不然中间就用冒号:引用

    console.log(sex);//当对象中没有时,可以用等号设置默认值 --> sex is not defined 测试先屏蔽上面的定义不然一样会打印
</script>
  1. 数组
	//数组解构
    const xiaoming = ['1','2','3','4'];
    const [a,b] = xiaoming;
    console.log(a,b)//按照索引进行取值的
    const [k,...values] = xiaoming;//后面的几个原属就会赋值到新的values中  --> 三个点...扩展运算符 --> 剩余参数
    console.log(k,values);

    //利用解构赋值交换变量值
    let v1 = '哈哈';
    let v2 = '喜喜';
    [v1,v2] = [v2,v1];
    console.log(v1,v2);
8. for of 循环以及对比
    const names = ['小明','校长','晓东','小溪'];

    //传统for循环 --> 缺点:书写麻烦
    for(let i =0;i<names.length;i++){
        console.log("传统for循环 = "+names[i]);
    }

    //数组forEach循环 --> 缺点:不能break和continue
    names.forEach(name => {
        console.log("forEach循环 = "+name);
    })

    //for in循环 --> 缺点:对象是索引同时会遍历对象的属性,产生污染的数据
    //比如:
    names.myshuxin = '这时候for in %%方法也会把这个遍历出来';
    Array.prototype.haha = '这时候for in @@方法还是会把这个遍历出来'
    for(let index in names){
        console.log("for in循环 = "+names[index]);
    }

    //厉害的for of 循环 --> 好,很好,非常好  ~  但是不支持对象!!!!!!!!!!!!!!!!!!!!!!!!!
    for(let name of names){
        console.log("for of循环 = "+name);//循环出的直接是值,不在是forin中的索引了
    }

    //for of 同时取索引值和值
    for(let nameObj of names.entries()){
        console.log(nameObj);// [1, "校长"]
        console.log("for of循环 = index:"+nameObj[0]+",value:"+nameObj[1]);//这个时候值是个新对象包含索引和值
        //for of循环 = index:0,value:小明
    }

    //for of 同时取索引值和值 --> 解构写法
    for(let [index,name] of names.entries()){
        console.log("for of循环 = index:"+index+",value:"+name);    //for of循环 = index:0,value:小明
    }

    //for of 循环对象未定义会报错 others is not defined
    for(let other of others){
        console.log("for of循环 = "+other);//循环出的直接是值,不在是forin中的索引了
    }
9. Array.from() 和Array.of()
<body>
    <div>
        <ul>
            <li>AAAAAA</li>
            <li>BBBBBBBBBB</li>
            <li>CCCCCCCCC</li>
            <li>DDDDDDDDD</li>
        </ul>

    </div>
</body>
<script>
    //类数组对象就是有length属性的对象
    let lis = document.querySelectorAll("li");
    console.log(lis);//length: 4  __proto__: NodeList --> 不是Array数组是NodeList,同时又length属性

    //let liTexts = lis.map(li => li.textContent);
    //console.log(liTexts)
    //错误Uncaught TypeError: lis.map is not a function
    //错误原因lis是类数组但是不是数组所以没有map属性,调用map就会报错,必须把它转换成Array对象才能调用map

    //讲类数组转换成数组
    let newLis = Array.from(lis);
    let liTexts = newLis.map(li => li.textContent);
    console.log(liTexts);

    //箭头函数简化以及Array.from(类数组,执行方法)
    let newLiTexts = Array.from(lis,li => li.textContent);
    console.log(newLiTexts);

    let array1 = new Array(1);//表示长度为1的数组,所以不会将1作为值存储
    console.log(array1)
    let array2 = Array.of(1);//表示将1的值存入数组,of就这点作用  --> 注意没有new 
    console.log(array2)
</script>
10. Array的find()函数和findIndex()函数

效率比各种for循环的效率高,找到后后面的就不会执行了

//element是当前的元素,index当前元素的索引值,array数组本身
const 结果 = 数组.find((element,index,array) => {
	if(element.某属性 === 什么什么){
		return true;
	} else {
		return false;
	}	
});
//进一步简写方法
const 结果 = 数组.find( element => element.某属性 === 什么什么)//箭头函数的隐式返回

//结果是个索引值
const 结果 = 数组.findIndex( element => element.某属性 === 什么什么)//箭头函数的隐式返回
11. Array的some()函数和every()函数

some函数:数组中某属性有一个满足条件,就立即返回true,后面的不在遍历
every函数:数组所有的某个属性值都满足某条件时才会返回true

const 布尔值 = 数组.some( value=> value.某属性 > 某值);
const 布尔值 = 数组.every( value=> value.某属性 < 某值);
12. 剩余参数
const xiaoming = ['小明',12,'学习','听歌','玩手机'];
const [name,age,...likes] = xiaoming;//数组解构,同索引对应原索引值
console.log(name,age,likes);//小明, 12, (3) ["学习", "听歌", "玩手机"]
13. 扩展运算符

使用扩展运算后对象指向新的地址,不在是原来的地址,修改原数据或者新数据对对方无影响
提到concat函数,concat函数内存地址不变更,修改新,就会修改原有数据

  1. 常规使用
const value1 = ['qwe','weqwewq','retertre'];
const value2 = ['bdf','trey','ukyu'];
const newValue = [...value1,'中间捣乱',...value2];
console.log(newValue);
const newnewValue = [...newValue];
newValue[0] = '我改变了值,但是扩展运算后得到的时新的数组,指向的是新的地址,不再是使用同一个内存地址,所以这个只有newValue有效';
console.log(newValue);
console.log(newnewValue);
//["qwe", "weqwewq", "retertre", "中间捣乱", "bdf", "trey", "ukyu"]
//["我改变了值,但是扩展运算后得到的时新的数组,指向的是新的地址,不再是使用同一个内存地址,所以这个只有newValue有效", "weqwewq", "retertre", "中间捣乱", "bdf", "trey", "ukyu"]
//["qwe", "weqwewq", "retertre", "中间捣乱", "bdf", "trey", "ukyu"]

//字符串转换成字符数组
let arr = "ABCDE";
let arrHaha = [...arr];//使用扩展运算符...转换
console.log(arrHaha);
  1. 函数中使用
//扩展运算符在函数中使用
const value1 = ['qwe','weqwewq','retertre'];
const value2 = ['bdf','trey','ukyu'];
value1 .push(...value2);//这样就不在一个一个for似的push了,一次性搞定

const time= [2020,12,31];
let date = new Date(...time)
14. 标签中的字符串拼串
//ES5语法拼串
 <router-link :to="'/home/messages/detail/'+msg.id"></router-link>
//ES6语法拼串 
 <router-link :to="`/home/messages/detail/${msg.id}`"></router-link>
15. 对象定义的时候最好是用{}不要用null,容易报错
//当页面有调用的时候会报错
 const user = null;
//不会报错
 const user = {};

二、js模块化-ES6语法

1.使用方式
导入模块 export
引入模块 import
2.实现以及兼容

a. 使用babel将ES6编译为ES5代码
b. 使用Broweeserify编译打包成js

let msg = "hello";  //ES6
var msg = "hello";  //ES5

let fun = () => {}; //ES6
var fun = function fun(){}; //ES5
3. 安装browserify,babel
npm install babel-cli browserify -g
npm install babel-preset-es2015 --save-dev

babel 安装说明

4.练习 - 普通暴露
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script type="text/javascript" src="js/dist/app.js"></script>
<body>
<div>
    <p>1.先在当前文件的根目录下安装bable</p>
    <p>D:\WorkSpace\webWorkSpace\simple_practise\20200219-ES6-module>npm install babel-preset-es2015 --save-dev</p>
</div>
<div style="margin-top: 20px">
    <p>2.使用babel将ES6语法编译为ES5代码(但包含CommonJS语法)</p>
    <p>语法:babel js/src -d js/文件地址</p>
    <p>测试:babbel js/src -d js/lib</p>
</div>
<div style="margin-top: 20px">
    <p>3.使用browserify打包成一个js文件</p>
    <p>语法:browserify js/lib/app.js -o js/输出的文件地址/输出的文件名</p>
    <p>测试:browserify js/lib/main.js -o js/dist/app.js</p>
</div>
<div style="margin-top: 20px">
    <p>4.页面引用这个other.js</p>
    <p>script type="text/javascript" src="js/输出的文件地址/app.js"</p>
</div>
<div style="margin-top: 20px;color: red">
    <h3>注意事项</h3>
    <p>
        1. 引入自己写的js文件时 import xxx from 的这个路径要使用合适的路径,就算在同一个目录下也要加"./"否则可能出错,引入第三方库是直接写包名,比如jqyery!!!
    </p>
    <p>
        2. 引入的模块元素不能有重名,比如module1.js里面有haha方法,那么module2.js里面有haha方法导入时就会报错
    </p>
</div>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值