JavaScript ES6语法学习笔记 01、ES6语法基础
@[toc]
前言
本篇博客是关于javascript的ES6语法基础,若文章中出现相关问题,请指出!
所有博客文件目录索引:博客目录索引(持续更新)
一、认识ES6
ECMAScript
是语言的标准。ES6指的就是ECMAScript
这个语言标准的第6代标准。
ECMA
:是欧洲计算机制造商协会以及标准化组织。
历史版本:ES1-3、ES5-6
- ES4:由于语法变化太大,就被抛弃了。
ES3
(最广泛使用的):含有do while、switch、正则表达式等。ES5
:出现forEach、map、filter、Object.create()、Object.defineProperty等。- ES6:比较重要的一些知识点。
ES与js的关系:JavaScript(浏览器端)=ECMAScript(语法+API)+DOM+BOM
ES6兼容性:主流浏览器的最新版本几乎全部支持ES6
,除了IE
老版本等不支持的浏览器,可以使用Babel
转码。
二、认识let与const
2.1、初识let与const
在ES6
之前仅仅只有var
来定义变量,ES6
之后带来let
、const
。
- 其中
var
、let
用来定义声明变量,const
来定义常量。
①赋值情况
const
必须在定义时就进行初始化,如const a = 15;
,不能在声明之后再进行赋值会报错!
②const
注意事项
基本类型:对于基本类型值一旦定义并赋值之后就不能够重新赋值。
引用类型:同样赋值之后不能够重新赋值,但是对于对象其中的属性是可以进行赋值的。
const应用场景:定义一个变量时若是不知道想要使用什么来定义,就可以先使用const,等待后面若是出现报错情况,再进行修改调整定义方式。
2.2、let、const与var的区别(5点)
区别包括以下几点内容:
- 重复声明:
var
允许重复声明;let
与const
不允许。 - 变量提升:
var
会提升变量的声明(在函数中定义的并不会向外提升,其他作用域会);let
、const
不会提升变量的声明。 - 暂时性死区:只要作用域内存在
let
、const
,它们所声明的变量或常量就自动"绑定"这个区域,不再受到外部作用域的影响(如内部有了一个a,其声明上头不能去使用a);var
的话是可以去向上查找的。 - 块级作用域:
var
没有块级作用域(如for
、while
之类,function()
属于函数作用域,其中用var
定义的不会进行变量提升);let
、const
有块级作用域,定义声明只在这个作用域内。 - window对象的属性和方法(全局作用域):var在全局作用域中声明的变量、函数会自动变量window对象的属性与方法;let与const并不会!
第二部分:重复声明
var
仅允许在自己的本作用域中进行变量声明提升。(更不用说let与const了一致!)
<script>
function fun() {
//测试一:在函数内部的for循环中进行定义i
// for (var i = 0; i < 3; i++) {
// }
//测试二:直接在函数中定义i
var i = 10;
}
fun();
//两个测试都没有能够获取到!
console.log(i);
</script>
暂时性死区
对于var:没有暂时性死区的问题
<script>
var i = 1;
function fun() {
console.log(i);//undefined
var i = 10;
}
fun();
</script>
对于let、cosnt有暂时性死区问题:
<script>
let i = 1;
function fun() {
console.log(i);//由于暂时性死区的问题,其不能向外获取到i的值
let i = 10;//const同样效果
}
fun();
</script>
第五部分:window对象的属性与方法
2.3、let、const应用
引出var变量问题(使用在局部作用域中)
需求:我们为页面上的三个按钮添加点击事件,每点击一个按钮输出对应的数字。
<style>
* {
margin: 0;
padding: 0;
}
button {
width: 100px;
height: 100px;
border: 1px solid #000;
}
</style>
<body>
<div>
<button>0</button>
<button>1</button>
<button>2</button>
</div>
<script>
var btns = document.getElementsByTagName("button");
//方式一:普通进行遍历绑定单击事件(全局作用域问题)
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
console.log(i);
}
}
</script>
</body>
问题描述:点击任何一个按钮输出的内容竟然是3,原因就是出在在局部作用域中使用var变量,会有变量声明的情况!
画图来描述作用域
解决方案1(ES6解决方案):使用闭包
<script>
var btns = document.getElementsByTagName("button");
//方式一:普通进行遍历绑定单击事件(全局作用域问题)
for (var i = 0; i < btns.length; i++) {
//闭包:保存index值在函数作用域中
(function (index) {
btns[index].onclick = function () {
console.log(index);
}
})(i);
}
</script>
画图:对应的作用域
解决方案2:使用let、const来定义变量
<script>
var btns = document.getElementsByTagName("button");
//方式一:普通进行遍历绑定单击事件(全局作用域问题)
for (let i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
console.log(i);
}
}
</script>
画图:对应的作用域
三、模板字符串(``)
3.1、认识模板字符串与基本使用
介绍模板字符串类型
语法:通过使用``包裹。
<script>
//模板字符串与普通字符串实际是同样类型的(都是string)
let commonStr = 'changlu';//普通字符串也可以使用''、""
let str = `changlu`;
console.log(commonStr === str);//模板字符串也是字符串类型
</script>
说明:模板字符串与普通字符串类型一致,只不过比普通字符串多增加了一个注入功能,更加方便合成字符串。
基本使用
我们来看看模板字符串怎么进行拼接字符串的,通过使用${}
来传入即可!!!特别的方便相对于普通字符串进行拼接:
<script>
var obj = {
name: "changlu",
age: 16,
height: 160
};
//使用模板字符串进行拼接
let str = `name:${obj.name},age:${obj.age},height:${obj.height}`;
console.log(str);
</script>
3.2、注意事项(输出多行字符串、特殊字符、注入哪些内容)
输出多行字符串
普通字符串:需要使用\n进行换行。
模板字符串:``之间相隔距离即可进行换行,\n也能够实现换行。
<script>
//普通字符串:使用\n表示换行,其中使用\来表示拼接意思
let str = '123 \n \
';
//模板字符串,按照直接留有的空白内容即可进行换行
let str1 = `456
`;
console.log(str);
console.log(str1);
</script>
特殊字符串
想要使用模板字符串输出特殊字符如’ \等,只需要在前面添加\即可,与普通字符串一致:
<script>
let str = `'\`\\`;
console.log(str);//'`\
</script>
注入内容
**使用 {}`进行注入到模板字符串中。比如说一些数字运算,获取对象中的值,函数等等…
<script>
//常量
const num = 10;
//变量
let a = 1;
//对象
var obj = {
name: 'changlu',
sex: 1,
age: 18,
speak: function () {//函数
return "我是obj对象";
}
};
//模板字符串注入变量、变量进行运算、三元运算符、函数都是允许的
let str = `num:${num} \na+1=${a + 1}
obj中的内容:obj.name=${obj.name},obj.sex=${obj.sex === 1 ? '男' : '女'},obj.age=${obj.age}
执行函数:${obj.speak()}
`;
console.log(str);
</script>
3.3、实际应用(将标签与对象值进行配合进行注入)
模板字符串主要应用场景:就是将HTML标签以及相关信息结合起来,通过这种形式注入进来。
需求:将对象中的数据插入到标签字符串里,最后配合dom元素的innerHtml属性在浏览器上显示。这里使用定时器来展示出这个效果!
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 300px;
height: 300px;
margin: 10px auto;
}
div p:nth-child(1) {
color: red;
}
</style>
<body>
<div>
<p>信息表</p>
<p id="info">等待信息载入中...</p>
</div>
<script>
var dom_p = document.getElementById("info");
//数组包含了三个对象
var objInfo = [{
name: "changlu",
age: 18,
sex: '男'
}, {
name: "liner",
age: 23,
sex: '女'
}, {
name: "xiaoming",
age: 10,
sex: '男'
}];
//插入信息操作
function insertSecondP() {
dom_p.innerHTML = "<ul>";
//遍历数组,将所有的信息插入到标签中
for (let i = 0; i < objInfo.length; i++) {
dom_p.innerHTML += `<li>name:${objInfo[i].name},age:${objInfo[i].age},nasexme:${objInfo[i].sex}</li>`
}
dom_p.innerHTML += "</ul>";
}
//演示2秒载入到dom元素中
setTimeout(insertSecondP, 3000);
</script>
</body>
四、箭头函数(简化函数写法)
4.1、认识箭头函数
语法结构:() => {}
,其实这个表达式我们就可以看做function (){}
,其就表示一个匿名函数。
初始使用:
<script>
//可设置两个参数并进行返回(完整写法)
const add = (x, y) => {
return x + y;
};
console.log(add(1, 2));
</script>
4.2、箭头函数的简化写法
单个参数:
//原始写法:单个参数
const add = (x) => {
return x;
};
//简化写法:单个参数可以省略()
const add = x => {
return x;
}
单行函数体:
//原始写法:函数体包含 单行返回语句+{}包裹
const add = x => {
return x;
};
//简化写法:对于单行返回值可以省略{}与return,注意必须同时一起省略,不能去掉{}留一个return
const add = x => x;
单行对象:
//原始写法:返回一个对象 {}+return
const add = x => {
return {
age: 18,
name: "changlu",
x: x
};
};
//简化写法:去除{}与return,使用()包裹。注意返回对象时不能直接外面套一个{}否则js会认为是一个函数体,所以需要使用()包裹表示一个对象。
const add = x => ({
age: 18,
name: "changlu",
x: x
});
注意:对于上面使用箭头函数简写,都是针对于单行的,如单行参数、函数体、对象,一定要遵守其使用方法!!!
4.3、箭头函数中的this指向
回顾一下全局作用域中以及一般函数里的this指向
<script>
// 'use strict';
//1、直接打印this
console.log(this);//window
//2、打印函数中的this对象
function add() {
console.log(this);
}
add();//非严格模式下输出:window;严格模式下输出:undefined。
//其实直接调用add()函数,实际上是没有对象调用的,所有严格模式下输出undefined
</script>
注意:只有在函数被调用的时候this指向才确定,不调用的时候,不知道指向谁。
箭头函数中的this指向
箭头函数中的this指向:箭头函数没有自己的this。
总结:对象调用自己的箭头函数属性输出的this
是window
;只有在下面3中才能够让箭头函数输出一个对象就是在箭头函数外再定义一个函数。
<script>
'use strict';
//1、在匿名函数中获取this
const add = () => console.log(this);
add();//window | 严格与非严格模式下都是window
//2、对象中定义一个匿名函数给一个参数(箭头函数)
const calc = {
add: () => {
console.log(this);
}
};
calc.add();//window | 若是普通函数定义给add,则会输出calc对象
//3、在函数中定义一个匿名函数
const calc1 = {
add: function () {
const adder = () => this;
console.log(adder());
}
};
// calc1.add();//calc对象
var add1 = calc1.add;
add1();//严格模式下:undefined;非严格模式下:undefined | 实际就是调用的普通函数
</script>
4.4、箭头函数应用(利用箭头函数没有this特性)
需求:使用一个对象来表示一个定时器,点击按钮,绑定单击事件,接着进行计时!
没有学习箭头函数前:我们通过使用一个变量来暂存对象
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100px;
overflow: hidden;
margin: 10px auto;
}
</style>
<body>
<div>
<button>点击开始</button>
<span id="myspan">0</span>
</div>
<script>
var btns = document.getElementsByTagName("button");
var myspan = document.getElementById("myspan");
//定时器对象
const timer = {
time: 0,
start: function () {
var self = this;//保存对象的this指向
btns[0].onclick = function () {
setInterval(function () { //要想在这里使用timer对象里的属性就需要提前保存对象中的属性
//console.log(self); //用来测试
myspan.innerText = self.time;
self.time++;
}, 1000);
}
}
};
timer.start();
</script>
</body>
学习使用箭头函数后
通过利用箭头函数里没有this对象的特性,就会继续向上找的特性,让其自己找到对象的this即可!
//定时器对象
const timer = {
time: 0,
start: function () { //3、下面两个都设置箭头函数时,this继续向上找到timer对象
btns[0].onclick = () => {//2、下面改为箭头函数时,这里依旧是普通函数时,就是button按钮
setInterval(() => { //1、设置普通函数时,setInterval()是window;设置箭头函数后默认没有this向上找
console.log(this);
myspan.innerText = this.time;
this.time++;
}, 1000);
}
}
};
五、解构赋值(数组、对象、其他类型快速赋值)
解构赋值
:解析某一数据的结构,将我们想要的东西提取出来,赋值给变量或常量。
5.1、数组解构赋值
5.1.1、引出数组结构赋值与语法
引出数组结构赋值
//曾经获取数组的三个值
const arr = [1, 2, 3];
console.log(arr[0], arr[1], arr[2]);//1 2 3
//数组解构赋值
[a, b, c] = [1, 2, 3];
console.log(a, b, c);//1 2 3
语法
数组模式结构匹配:[a,b] = [1,2]
。[a,b]前面是否使用let、const或var根据需求来使用。
注意:在前面[]中的a,b也会进行变量声明的,之后若是重新定义变量a或b就会报出异常!
案例:
//案例1:获取到数组中的每个元素
[a, b, c] = [1, 2, 3];
console.log(a, b, c);//1 2 3
//案例2:获取到数组中的第1,3个元素
let [d, , e] = [4, 5, 6];
console.log(d, e);//4 6
5.1.2、数组解构赋值的默认值
默认值语法:[a=1,b=2] = [3,4]
。想要使用默认值仅需在前面使用=即可。
1、若是没有匹配得到的值就会赋值undefined。
//若是没有匹配到就会默认赋值为undefined
let [a, b] = [1]; //此时默认可以看做是[1,undefined]
console.log(a, b);//1 undefined
2、默认值生效条件是必须匹配到undefined,其他值不会触发默认值生效。
//情况1:没有undefined,有null和其他值不会生效
let [a = 2, b = 3] = [1, null];
console.log(a, b);//1 null
//情况2:没有匹配到或者设置为undefined,默认值就会生效
let [c = 4, d = 5] = [undefined]; //[]实际你可以看做是[undefined,undefined]
console.log(c, d);//4 5
3、默认值设置为函数调用,其是惰性的,只有默认值生效时才会调用!
function fun() {
console.log("fun()调用了!");
return 1;
}
//情况1:不使用默认值时,不会调用函数
let [a = fun()] = [6];
console.log(a);
//情况2:使用默认值时,才会调用函数
let [b = fun()] = [];
console.log(b);
实际应用场景(数组与类数组、函数传参、交换值)
对于一些数组或是数组,从其中获取到执行值就可以使用结构赋值方式,如函数中的arguments
、NodeList
都是可以的:
情景1:①调用一个函数过程中,需要获取到arguments
里的第1,3个值。②NodeList进行赋值解析
//arguments测试
function fun() {
//原来获取arguments方式
//console.log(arguments[0],arguments[2]);
//使用数组解构赋值获取到arguments的1、3个值
[a, , b] = arguments;
console.log(a, b);
}
fun(1, 2, 3);//1,3
//NodeList测试
<div>
<a href="">1</a>
<a href="">2</a>
<a href="">3</a>
</div>
<script>
//对于类数组如NodeList即可使用解构赋值方式
const [a1, a2, a3] = document.querySelectorAll("div a");
console.log(a1);
console.log(a2);
console.log(a3);
</script>
情景2:函数传参数为数组时,可使用解构赋值形式来获取对应参数
//数组结构赋值,第二个设置默认值为2
function fun([x, y = 2]) { //原本参数设置为arr,现在可以看做[x,y=2]=arr
console.log(x, y);
}
fun([1]);//1 2
情景3:交换变量
let [a, b] = [1, 2];
//原始交换变量方式
// let temp = a;
// a = b;
// b = temp;
// console.log(a, b);//2,1
//使用数组解构赋值
[a, b] = [b, a];//首先先是右边进行赋值为[2,1],接着来进行[a,b] = [2,1]达到交换变量方式
console.log(a, b);//2,1
5.2、对象解构赋值
5.2.1、语法以及原理分析
语法介绍
语法(模式匹配):{}={}
普通获取对象值与解构赋值区别:
var obj = {
name: "changlu",
age: 18
};
//普通方式
console.log(obj.name, obj.age);//changlu 18
//对象解构赋值(这里是简略写法)
let { name, age } = obj;
console.log(name, age);//changlu 18
原理分析
上面的区别介绍中使用的实际上是简略写法,下面的才是完整写法,一般不使用别名时就使用简略写法:
var obj = {
name: "changlu",
age: 18
};
//对象解构赋值
//简略写法:{}其中的变量名应当与对象中的key名称一致
//let { name, age } = obj;
//本质实际上name=>name:name age=>age:age
//完整写法如下:分析一下name:name,第一个name用来进行去对象中匹配的,第二个name是匹配到之后进行赋值到该变量中
let { name: name, age: age } = obj;
console.log(name, age);//changlu 18
5.2.2、注意事项(含默认值说明)
1、对于对象进行解构赋值时,若是前面没有定义关键字时,需要在整个表达式上加上(),否则js
会认为其是一个代码块。
//有let关键字进行定义
//let { name: name, age: age } = { name: 'changlu', age: 18 };
//无关键字进行定义时:需要在整个表达式上加上(),否则会出现异常
({ name: name, age: age } = { name: 'changlu', age: 18 });//如({} = {})这种样式
console.log(name, age);//changlu 18
2、默认值同样也是匹配不到时生效,也可设置默认值,若是默认值是函数会惰性执行。
//其中b匹配不到对应值,就会生效默认值
let { a, b = 1 } = { name: "changlu", a: 1 };
console.log(a, b);//1 1
3、对象中可以取到继承的属性
//自定义对象的原型对象里的__proto__默认指向了Object,那么也就能够获取到Object中的方法
let { toString } = {};
console.log(toString);
5.2.3、设置别名参数获取值
完整对象解构赋值为:{name:name}其中第一个name是用来去匹配的,第二个name才会真正得到值的你可以拿到的。
-
注意:第一个name你是无法输出其值的,因为你根本就没有定义,定义的是:之后的变量名,该案例只有在使用别名测试中才能得到体现。
-
//测试获取:前的变量,会出现变量未定义的情况 let { name: n, age: a } = { name: "changlu", age: 18 }; console.log(name, age);//changlu 18
两个小案例:
//1、取别名,:后的就是对应的别名
let { name: n, age: a } = { name: "changlu", age: 18 };
console.log(n, a);//changlu 18
//2、取别名+设置默认值。为s设置默认值,默认值设置在:后的参数中
let { n: name, a: age, s: sex = '男' } = { n: "changlu", a: 18 };
console.log(name, age, sex);//changlu 18 男
实际应用场景(函数传参、对象取值)
案例1:函数的参数中使用对象解构赋值
// 传入一个对象
function fun({ name = "liner", age = "20" }) {
console.log(name, age);
}
//测试一:传入一个带有值的对象
fun({ name: "changlu", age: 18 });
//测试二:传入一个没有值的对象
fun({});//此时输出默认值
案例2:从复杂对象嵌套中取值,包含了从对象中取到数组、对象以及对应数组、对象中的某个值
最最重要记住一点就是:在对象解构赋值中是根据key来匹配的,并不是根据顺序来进行赋值的。
const obj = {
x: 1,
y: [2, 3, 4],
z: {
a: 5,
b: 6
}
};
//目标:取到y数组(y),y数组中的第二个数(a),z对象(z),z对象中的b(b)
let {
y, //直接匹配到y,接着定义y变量,并赋值到y变量中 | 展开就是y:y
y: [, a], //匹配到y,将数组[2,3,4]赋值给[,a],自然a就得到了其数组的第二个元素
z, //直接匹配到z,依旧定义以及赋值到z变量中
z: { b } //匹配到z,将对象{a:5,b:6}赋值给{b},其中b依旧进行key名匹配得到值!
} = obj;
console.log(y, a, z, b);
5.3、其他类型(字符串、数值、布尔、undefined与null)
字符串
字符串解构赋值:可使用数组、对象解构赋值两种方式进行。数组方式采用顺序进行赋值;对象方式采用下标来进行匹配得到值。
let str = "abcde";
//数组解构赋值方式:按照顺序来匹配单个字符即可
let [a, b, c, d, e] = str;
console.log(a, b, c, d, e);//a b c d e
//对象解构赋值方式:根据字符串下标位置来匹配,写成如{下标位置:赋值变量}形式
let { 0: a1, 1: b1, 2: c1, 3: d1, 4: e1 } = str;
console.log(a1, b1, c1, d1, e1);//a b c d e
数值与布尔:只能够通过对象解构赋值方式进行获取
说明一点:对于数值与布尔类型我们是无法获取其中的某个部分值,但是能够获取到其继承的函数变量。
- 这两个基本类型其原型链指向了各自的包装类。
//数值与布尔类型都能够使用对象解构赋值方式来获取值
//1、对于数值,无法通过解构赋值来获取其中的值,但能够获取继承的函数变量
// let { a = 1, toString } = 1234;
// console.log(a, toString);//1 ƒ toString() { [native code] }
//2、对于布尔类型,同样不能获取其中的值,但能够获取继承的函数变量
let { b = 2, toString } = true;
console.log(b, toString);//2 ƒ toString() { [native code] }
undefined与null:不能够通过解构赋值方式获取
说明:undefined与null都是基本数据类型,并且其自身是没有原型链的!自然也就不能够解构赋值方式获取任何东西!
//undefined与null都是基本类型,所以下面的测试其实也没有什么意义
let { toString } = undefined;
console.log(toString);//报异常,显示未定义
// let { toString } = null;
// console.log(toString);//报异常,显示未定义
总结
数组解构赋值
:其是通过数组元素的顺序来进行赋值给变量的。
对象解构赋值
:其是通过匹配key的形式获取到的值。简写{a,b}={a:'a',b:1}
,其中{a,b}的完整形式是{a:a,b:b}
,第一个a是用来匹配的,第二个a才是进行赋值的。我们进行取别名获取取某个值中的值就一定需要使用完整形式,其他普遍情况使用简写即可。
- 注意:若是没有关键字定义则需要将整个表达式()起来才会生效,否则js会认为其是代码块。如
({a,b}={a:1,b:2})
。
其他类型:
字符串解构赋值
:可使用数组、对象的方式来获取某个char字符。数组就是默认按顺序获取,对象则是通过书写下标:变量
进行获取值。数值与布尔
:不能够获取到其中的值,但是能够获取到继承到的函数值(因为其有包装类)。undefined与null
:两个是基本类型,都不能获得值以及继承到的函数值。
对于解构赋值应用:如快速交换变量、函数传参并能够设置默认值、取数组或类数组以及对象的值,我认为是很多地方都能够使用到的!
六、对象字面量
6.1、普通创建对象与对象字面量
对象字面量:实例化构造函数生成对象。
下面例子看一下普通创建对于与创建字面量两种形式:
//普通创建一个对象(或者自定义一个构造函数,使用new来创建对象)
var obj = new Object();
obj.name = "changlu";
obj.age = 18;
console.log(obj);//{name: "changlu", age: 18}
//对象字面量方式
var obj2 = {
name: 'changlu',
age: 18
};
console.log(obj2);//{name: "changlu", age: 18}
6.2、对象字面量属性与方法简洁表示
简而言之:以前在对象里引用外部一个属性或者方法通常使用变量名: 引用变量名
或函数名: 引用函数
,其实只需要直接将该变量或变量函数直接传入到对象中,就会自动为你生成key、value(对应传入的键值)。
下面是对于对象字面量属性与方法的简洁表示:
//以前为一个对象添加属性name及值方式
//方式一:外部.属性形式添加
// const obj;
// obj.name = "changlu";
//方式二:在对象内部添加
// const name = "changlu";
// const obj = {
// name: name //使用外部变量
// };
//对象字面量简洁写法
//属性简洁写法
const name = "changlu";
const obj = {
name
};
console.log(obj);
//方法简洁写法
const info = () => console.log("I am info方法!");
const obj2 = {
//以前写法
// speak: () => "speak方法!";
speak() { //简洁写法一
console.log("speak方法!");
},
info //简洁写法二:直接传入函数方法
};
console.log(obj2);
obj2.speak();
obj2.info();
6.3、对象字面量中的方括号语法(key能够使用[]进行书写)
使用位置:在对象字面量中[]
使用于key中。在[]中也可以写任何能够获得值的变量或者说表达式,只要能够返回值的即可。
用途:能够更加方便的设置对象中的键(也就是key)的值,对于一些键我们可以直接通过使用[]形式直接设置在对象中,而不用在外面进行运算后再传入。
实际案例:在[]中尝试使用各种获取值的形式,都是允许的
const name = 'name';
const fun = () => 'sex';
const person = {
[name]: "changlu", //引入外部变量
[fun()]: '男', //调用函数获取值
['ag' + 'e']: 18, //字符串拼接
['12_op']: null, //非合法变量名
[10 + true]: 11 //数学运算
};
console.log(person);
//获取其中的值,对于字面值可以使用.属性获取,对于一些非合法变量名需要使用[]来获取
console.log(person[11]);
console.log(person.age);
七、函数参数的默认值
7.1、认识函数参数的默认值
回顾之前:之前学习的是解构赋值中的默认值使用,也就是数组形式与对象形式的,如数组形式[a=1,b=1]=[1,2]
,对象形式{name='liner',age=18}={name:"changlu",age=20}
,这些默认值只有在匹配不到相应的值或undefined时就会生效!
函数参数的默认值:对于函数中的参数列表,ES6
提供了给函数参数添加默认值!!!
示例:
//对于函数参数,我们也可以设置默认值。一旦匹配不到值或为undefined就会生效默认值
//对于默认值设置为函数是会惰性加载的,默认值生效才会加载
function fun(name, age = 16, sex = '女', height = 180) {
console.log(name, age, sex, height);
}
fun("liner");//liner 16 女 180
实际应用场景(函数默认值+对象解构赋值)
需求:传入一个对象,对象中的三个属性在函数接收时必须赋值,给该函数传入对象或传入空都能够生效打印。
实现:看其中的最终实现
实现1:设置函数参数为一个对象,接着通过该对象获取其中的属性
function fun(obj) {
//将对象中的属性一个个进行输出,并且考虑为空情况
console.log(obj.name == undefined ? 'changlu' : obj.name,
obj.sex == undefined ? '暂无' : obj.sex,
obj.age == undefined ? '未知' : obj.age);
}
//测试一:传入一个完整对象(包含name、sex、age)
fun({
name: 'changlu',
age: 18,
sex: '男'
});
//测试二:传入一个不完整对象(只有name),此时不符合需求:age、sex为空
fun({
name: 'changlu'
});
//测试三:不传入任何值,此时不符合需求:出现name属性未定义
fun();
弊端:若是输出对象中的某个属性为undefined需要我们来进行额外判断;若是不传入属性,就会出现未定义的字样。
最终实现:函数默认值+对象解构赋值巧妙配合
// { name, age = 18, sex = '男' } 为 对象解构赋值,因为传入的是一个对象,通过解构赋值形式来匹配对应的键值,并设置默认值
// { name, age = 18, sex = '男' } = {} :解决了传入为空的情况,若是传入为空那么{ name, age = 18, sex = '男' }=undefined,自然就会报错
// 巧妙利用了函数参数默认值来赋值一个{}空对象,进而能够实现再次设置其中属性默认值的操作!!!
function fun({ name = "liner", age = 18, sex = '男' } = {}) {
console.log(name, age, sex)
}
//测试一:传入一个完整对象(包含name、sex、age)
fun({
name: 'changlu',
age: 18,
sex: '男'
});
//测试二:传入一个不完整对象(只有name),此时不符合需求:age、sex为空
fun({
name: 'changlu'
});
//测试三:不传入任何值,此时不符合需求:出现name属性未定义
fun();
精髓:{ name = "liner", age = 18, sex = '男' } = {}
这个作为函数的参数值!!!实在是妙呀!!!
- 点赞
- 收藏
- 关注作者
评论(0)