一、基础语法
1. const理解
当const是对象时,指向的时地址值,所以对象不可以改变但是,对象的属性时可以改变的
2. var,let,const如何选择
- var函数作用域,let、const块级作用域
- 默认使用const,如果变量需要重新赋值或更新使用let,尽量不使用var
3. 箭头函数理解
- 箭头函数 - 结构
<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>
- 箭头函数 - 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. 模板字符串
- 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>
- 方便的编写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>
- 引入方法,可以用来过滤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 []
- 对象
<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>
- 数组
//数组解构
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函数内存地址不变更,修改新,就会修改原有数据
- 常规使用
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);
- 函数中使用
//扩展运算符在函数中使用
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
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>