前言
在做项目的过程中我们少不了写一些js代码,或者是在面试过程中,也会遇到不少es6相关问题,这里会按具体问题出发,讲解es6那些我们模棱两可的问题
一、块级作用域
1.var的声明和变量提升(hositing)机制
console.log(a)
var a=1;
正常情况下,在没定义下调用,应该报错才对,但是因为var本身的变量提升机制,上述代码变成了:
var a;
console.log(a)
a=1;
结果如下: 2.let 相当于C语言的int ,必须先定义再访问。 这里的报错又叫 临时性死区 3.const ***通常用来定义常量***声明的是块级变量,和let相似。但是用它定义的常量不允许更改(报错): 主要用在定义对象上。对象里的变量可以修改 原因解释: 一般 基本数据类型 保存在 栈 当中:像刚才的数字a,保存在栈中 引用 数据类型 保存在 堆 当中:像刚才的obj对象保存在堆当中,堆当中的数据我们没有办法直接访问,所以我们需要拿出堆当中对象{}的地址,保存到栈中变量obj中,所以本例中obj保存的是对象的地址而不是本身而obj.name只是其中的一个键。 4.循环中的函数
问:编写代码,实现每隔一秒钟逐次打印0,1,2,3,4
你可能会想到用循环写,内部嵌套一个定时器即可,那么问题来了,变量i用var 定义还是let 使用var
for(var i=0;i<5;i++){
setTimeout(() => {
console.log(i)
}, i*1000);
}
输出结果: 使用let
for(let i=0;i<5;i++){
setTimeout(() => {
console.log(i)
}, i*1000);
}
结果: 很显然两者相比后者符合。 但是前者可以经过处理而符合我们的题意(定时器外嵌套一层函数):
for(var i=0;i<5;i++){
(function(e){
setTimeout(() => {
console.log(e)
}, e*1000);
})(i)
}
5.全局块作用域的绑定 用var定义的变量会直接挂载到window上,而let不会
总结:
- let const 不会变量提升
- let和const必须先定义再访问
- const定义的基本数据类型不可以更改 定义的引用数据类型可以更改
- let和const定义的变量会被限制在其作用域但中,不能被外部访问。
二、es6函数
1.默认参数问题 对于如下es5函数: 可以发现其中对于“”的输入,返回的是null而非“”本身,而且0的传入默认为了false然后返回了null,这是es5中存在的一个bug 对于es6函数: 可以发现,传入的0也返回出来了。空字符串也返回的是空字符串。而非不传参数时的1000和null。 2.处理无名参数 arguments又叫无名参数,是es5接受不定参数的方法 具体使用如下: 而es6接受无名参数的方法如下(使用三个点“…”形式): 3.展开运算符 可以将一个数组或者一个对象展开 …语法,可以展开对象、数组的值,可以用来合并、覆盖等操作(如下覆盖操作)
三、解构
1.对象的解构
var options = {
repeat : false,
save : false
}
var {repeat,save} = options;
就像抽取语法一样 2.数组的解构
var arr = [1,2,3,4]
var [a,b] = arr;
console.log(a,b)
3.嵌套数组
var arr1 = [1,[2,3]]
var [h,[k,l]] = arr1;
console.log(h,[k,l])
四、扩展对象的功能性
1.属性的简写
2.方法的简写
var obj1 = {
print: function () {
}
}
var obj2 = {
print() {
}
}
3.可计算的属性名 对象的访问语法:
var obj3 = {
name : 111,
age : 222
}
obj.name
obj['name']
es6可计算的属性名如下,方括号中进行了计算。 4. 对象新增的方法
双等比较:
- 双等号前后有没有NaN,如果存在NaN,一律返回false。
- 双等号前后有没有布尔值,有布尔就将布尔转换为数字(false是0,true是1)
- 字符串和对象, 此时对象会自动调用toString()或者valueOf()进行转换
- 字符串和数字,此时字符串要转化成数字
- 字符串和字符串,直接比较
- 字符串和除了上边的比较外,其他的比较全部返回false
- 数字和对象,此时对象取valueOf()或者toString()进行比较, 其他一律返回false
- null, undefined不会进行类型转换, 但它们俩相等
对应的例子:
console.log(NaN == 100);
console.log(true == 1);
console.log(false == 0);
console.log("abc" == {name : 1});
console.log("abc" == {name : "abc" , toString : function(){return this.name}});
console.log("100" == 100);
console.log("abc" == 'bcd')
console.log(100 == {age : 100 , valueOf:function(){return this.age}});
console.log(null == undefined);
三等比较
- 数据的类型是否一样
- 数据的值是否一样
对应例子:
console.log('100' === 100);
console.log(false === 0)
console.log(true === 1)
虽然看起来三等比较更严谨,但还是有一些bug
console.log(+0 === -0);
(完美解决所有三等不足,正确判断是否相等),es6新出了一个Object.is()方法,来解决双等和三等出现的一些问题
console.log(Object.is('100' , 100));
console.log(Object.is(+0 , -0)) ;
5.拷贝问题 对于下面代码
var obj6 = {
name : 1,
age : 2
}
var obj7 = obj6;
obj7.name = 100;
console.log(obj6);
我们可以发现,最后的输出,obj6的name值发生了改变,所以这种拷贝属于浅拷贝,两个对象拷贝的是地址,地址上的值发生改变,所以obj6上的值也发生了改变(只拷贝地址,而不是简单的拷贝值。
es6新增方法:Object.assign() 参数:1.目标对象 2.被拷贝的对象 后面参数名相同覆盖
五、基本数据类型
string number boolean null undefined
1.创建Symbol类型
var num = 100;
var first = Symbol('这是一个first');
var second = Symbol('这是一个second');
console.log(first , second);
2.Symbol使用方法
var third = Symbol('这是一个third')
var obj = {
[third] : 100,
age : 200
}
console.log(obj[third])
六、模板字符串
var str = 100;
console.log('今天我考了' + str + '分')
console.log(`今天我考了${str}分`)
|