1、var、let、const的区别
区别一:
var有变量提升,而let和const没有
<script>
console.log(str); //undefined
var str = "你好";
</script>
<script>
console.log(str); //
let str = "你好";
</script>
<script>
console.log(str); //
const str = "你好";
</script>
区别二:
var可以多次声明一个变量
let和const不能多次声明一个变量
<script>
var str = "你好";
var str = '我好'
var str = '大家好'
console.log(str); //大家好
</script>
<script>
let str = "你好";
let str = '我好'
let str = '大家好'
console.log(str); //大家好
</script>
<script>
const str = "你好";
const str = '我好'
const str = '大家好'
console.log(str); //大家好
</script>
区别三:
var、let声明变量、
const声明常量
var和let声明的变量可以再次赋值,但是const不可以再次赋值了。
<script>
var str1 = "你好";
let str2 = "我好";
const str3 = "大家好";
str1 = "哈哈";
str2 = "哈哈哈";
str3 = "哈哈哈哈";
console.log(str1); //哈哈
console.log(str2); //哈哈哈
console.log(str3); //报错,/* */Uncaught TypeError: Assignment to constant variable.
</script>
区别四:
var声明的变量没有块级作用域
let和const声明的变量有自身块级作用域
<script>
if (true) {
var str = "哈哈哈";
}
console.log(str);//哈哈哈
</script>
<script>
if (true) {
let str = "哈哈哈";
}
console.log(str);// ReferenceError: str is not defined
</script>
<script>
if (true) {
const str = "哈哈哈";
}
console.log(str);// ReferenceError: str is not defined
</script>
2、作用域考题
考题一:let和const没有变量提升性
<script>
console.log(str); //undefined
var str = "你好";
console.log(num); //报错
let num = 10;
</script>
考题二:
<script>
function demo() {
var n = 2;
if (true) {
var n = 1;
}
console.log(n); //1
}
demo();
</script>
<script>
function demo() {
let n = 2;
if (true) {
let n = 1;
}
console.log(n); //2
}
demo();
</script>
考题三:可以修改引用对象里面的值,不能直接修改本身
<script>
const obj = {
a: 1,
};
obj.a = 11111;
console.log(obj);
const arr = ["a", "b", "c"];
arr[0] = "aaaaa";
console.log(arr);
</script>
<script>
const obj = {
a: 1,
};
obj = {
a: 2,
};
console.log(obj);
const arr = ["a", "b", "c"];
arr = ["hh"];
console.log(arr);
</script>
直接报错。
3、合并两个对象
方式一:Object.assign
<script>
let a = {
a: 1,
b: 2,
};
let b = {
a: 4,
b: 5,
c: 6,
};
const obj1 = Object.assign(a,b);
console.log(obj1);
</script>
如果有相同的属性值,后者覆盖前者。
方式二:…扩展运算符
<script>
let a = {
a: 1,
b: 2,
};
let b = {
a: 4,
b: 5,
c: 6,
};
const obj1 = {...a,...b};
console.log(obj1);
</script>
方式三:自己封装方法
<script>
let a = {
a: 1,
b: 2,
};
let b = {
a: 4,
b: 5,
c: 6,
};
function merge(target, source) {
for(let key in source) {
target[key] = source[key];
}
return target;
}
console.log(merge(a, b));
</script>
4、箭头函数和普通函数的区别
1、this指向问题
箭头函数的this指向在定义的时候就决定了,不能通过(call、apply、bind)改变
箭头函数的this指向定义的时候,指向外层第一个普通函数,如果为最顶层则指向window。
<script>
let obj = {
a: function () {
console.log(this);
},
b:()=>{
console.log(this);
}
};
obj.a();
obj.b();
</script>
使用call改变this指向,无效果.
apply和bind同样。
<script>
let obj = {
a: function () {
console.log(this);
},
b:()=>{
console.log(this);
}
};
obj.a();
obj.b.call(obj);
</script>
2、箭头函数不能new(不能实例化成构造函数)
<script>
let obj = {
a: function () {
console.log(this);
},
b:()=>{
console.log(this);
}
};
let objA = new obj.a();
let objB = new obj.b();
</script>
3、箭头函数没有prototype(原型)
<script>
let obj = {
a: function () {
console.log(this);
},
b:()=>{
console.log(this);
}
};
console.log(obj.a.prototype)
console.log(obj.b.prototype)
</script>
4、箭头函数没有arguments
<script>
let ff = function () {
console.log(arguments);
};
let fn = () => {
console.log(arguments);
};
ff();
fn();
</script>
<script>
let ff = function () {
return fn = () => {
console.log(arguments);
};
};
ff()();
</script>
如果箭头函数的外层第一个普通函数有arguments,则改箭头函数的arguments为父级作用域的arguments。
我们可以通过Rest(剩余)运算符解决箭头函数没有arguments的问题。
<script>
let ff = function() {
console.log(arguments);
}
let fn = (...res) => {
console.log(res);
};
ff(1)
fn(1)
</script>
5、Promise有几种状态
- 使用promise的时候,给它一个承诺,我们可以将他划分为三个阶段
pending(待定)
,执行了executor,状态还在等待中,没有被兑现,也没有被拒绝fulfilled(已兑现)
,执行了resolve函数则代表了已兑现状态rejected(已拒绝)
,执行了reject函数则代表了已拒绝状态
- 简单理解:
- 你承诺自己明天开始好好学习(还未到明天,此时为
待定状态
) - 时光飞逝,到了第二天你去图书馆好好学习了(
已兑现状态
) - 时光飞逝,到了第二天你因为某些事情而无法去图书馆学习(
已拒绝状态
)
- 状态只要从待定状态,变为其他状态后,则状态不能再改变。
- 比如从
pengding状态
变为fulfilled状态
后,则不能在从fulfilled状态
变为rejected状态
。 - 同样从
pengding状态
变为rejected状态
后,则不能在从rejected状态
变为fulfilled状态
。
举个栗子:
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('成功了')
reject('失败了')
},1000)
})
p.then(resolve=>console.log(resolve)).catch(reject=>console.log(reject))
//成功了
当我调用
resolve
之后,在调用reject
是无效的,因为状态已经发生改变,并且是不可逆的。
6、find和filter的区别
区别一:返回的内容不同
filter 返回是新数组
find 返回具体的内容
区别二:
find :匹配到第一个即返回
filter : 返回整体(每一个匹配到的都返回)
<script>
let arr = [1, 2, 3, 4, 5];
let newArr1 = arr.find((item) => {
return item > 2;
});
let newArr2 = arr.filter((item) => {
return item > 2;
});
console.log(newArr1);
console.log(newArr2);
console.log(arr);
//都不改变原数组
</script>
7、some和every的区别
some ==》 如果有一项匹配则返回true
every ==》 全部匹配才会返回true
<script>
let arr = [1, 2, 3, 4, 5];
let newArr1 = arr.some((item) => {
return item > 2;
});
let newArr2 = arr.every((item) => {
return item > 2;
});
console.log(newArr1);
console.log(newArr2);
</script>
<script>
let arr = [1, 2, 3, 4, 5];
let newArr1 = arr.some((item) => {
return item > 0;
});
let newArr2 = arr.every((item) => {
return item > 0;
});
console.log(newArr1);
console.log(newArr2);
</script>