目录
js 在 2015年发布了新版本,被称为 es6,之后每年更新一个版本。自 es7 之后,就直接用年份命名了。
版本 | 年份 |
---|---|
es6 | 2015 |
es7 | 2016 |
es2017 | 2017 |
es2018 | 2018 |
1,let 和 const
1,会产生块级作用域。
if (true) {
const a = 1
}
console.log(a) // ReferenceError: a is not defined
下面如果用 var
会打印3个2。
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i)
}, 1000)
}
2,如何理解 const
定义的变量不可被修改?
指这个变量不能被修改
- 重新赋值,和修改这个对象的属性值是没有关系的。
const obj = {}
obj = 1 // TypeError: Assignment to constant variable.
obj.a = 1 // ok
- 自增
const a = 1
a++ // TypeError: Assignment to constant variable.
2,数组
1,for…of 用于遍历可迭代对象,也包括伪数组,比如 arguments
,NodeList
(querySelectAll 获取的)
2,判断是不是数组,Array.isArray()
3,解构数组
const arr = [1, 2, 3, 4, 5];
const [a, b] = arr; // 1 2
const [, , a, b] = arr; // 3 4
const [a, , b, c] = arr; // 1 3 4
const [a, b, ...c] = arr; // 1 2 [ 3, 4, 5 ]
4,数组去重
const arr = [1, 3, 4, 3, 6];
const newArr = [...new Set(arr)]; // [ 1, 3, 4, 6 ]
5,打平数组
参数为遍历的层级。
const arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
const arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
6,创建指定 length 的数组
Array(10).fill(0)
3,对象
1,Object.is()
MDN - Object.is(),判断2个值是否相同,和 ===
唯一的区别是:
Object.is(-0, +0) // false
Object.is(NaN, NaN) // true
-0 === +0 // true
NaN === NaN // false
Array.prototype.includes()
使用的就是Object.is()
的规则。
2,属性描述符
js 使用属性描述符,来描述对象中的每个成员。vue2 通过此特性实现响应式核心原理。
const obj = {
name: '下雪天的夏风',
age: 18
};
在 js 内部被描述为
{
// 属性 name 的描述符
name: {
value: '下雪天的夏风',
configurable: true, // 该属性的描述符是否可以被重新定义
enumerable: true, // 该属性是否允许被遍历,会影响for-in循环
writable: true // 该属性是否允许被修改
},
// 属性 age 的描述符,同理。
age: {
value: '18',
configurable: true,
enumerable: true,
writable: true
},
}
有 API 可以操作属性描述符
const obj = {
name: '下雪天的夏风',
age: 18
};
// 修改属性描述符
Object.defineProperty(obj, "name", {
value: "新值",
writable: false,
enumerable: false,
configurable: true,
});
// 获取属性描述符
Object.getOwnPropertyDescriptor(obj, "name");
// 输出
{
value: '下雪天的夏风',
writable: false,
enumerable: false,
configurable: true
}
1,属性描述符 writable: false
时,修改无效,但不报错。
2,当通过 Object.defineProperty
设置 configurable: false
后,就不能再次修改属性描述符了,会报错。
getter
和 setter
const obj = {};
let init;
Object.defineProperty(obj, "a", {
get() { // 读取属性 a 时,得到的是该方法的返回值
return init;
},
set(val) { // 设置属性 a 时,会把值传入 val,调用该方法
init = val
}
});
3,常用API
const obj = { name: "名字", age: "年龄" };
console.log(Object.keys(obj)); // [ 'name', 'age' ]
console.log(Object.values(obj)); // [ '名字', '年龄' ]
console.log(Object.entries(obj)); // [ [ 'name', '名字' ], [ 'age', '年龄' ] ]
还有一个,正好和 Object.entries()
相反。
const obj = Object.fromEntries([
["name", "名字"],
["age", "年龄"],
]); // { name: '名字', age: '年龄' }
4,得到除某个属性之外的新对象。
const obj = {
a: 1,
b: 2,
c: 3,
};
const { a, ...newObj } = obj; // newObj { b: 2, c: 3 }
//或
const newObj = {...obj}
delete newObj.a
·
4,函数
1,箭头函数
特点
- 不能使用
new
调用 - 没有原型,即没有
prototype
属性 - 没有
arugments
- 没有
this
关于原型:
普通函数:
箭头函数:
关于 arugments
:
function fun() {
const fun2 = () => {
console.log(arguments);
};
fun2(1, 2);
}
fun(3, 4); // [Arguments] { '0': 3, '1': 4 }
在箭头函数中,可以使用剩余参数代替 arguments
const fun = (a, ...args) => {
console.log(a, args); // 1 [ 2, 3, 4 ]
console.log(Array.isArray(args)); // true
};
fun(1, 2, 3, 4);
2,默认参数
const fun = (a, b = 1) => {
console.log(a, b);
};
fun(1, undefined); // 1 1
3,解构传参
const fun = (config = { page: 1, limit: 10 }) => {
console.log(config); // { page: 1 } { page: 2, limit: 10 }
};
// 这样才能使用默认值
const fun = ({ page = 1, limit = 10 } = {}) => {
console.log(page, limit); // 1 10 和 2 10
};
fun({ page: 1 });
fun({
page: 2,
limit: 10,
});
4,类语法
基础写法:
// 旧的写法
function User(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
this.fullName = `${firstName} ${lastName}`;
}
User.isUser = function(u){
return u && u.fullName
}
User.prototype.sayHello = function(){
console.log(`姓名:${this.fullName}`);
}
// es6 等效写法
class User{
constructor(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
this.fullName = `${firstName} ${lastName}`;
}
static isUser(u){
return u && u.fullName
}
sayHello(){
console.log(`姓名:${this.fullName}`);
}
}
继承关系
function Animal(type, name){
this.type = type;
this.name = name;
}
Animal.prototype.intro = function(){
console.log(`I am ${this.type}, my name is ${this.name}`)
}
function Dog(name){
Animal.call(this, '狗', name);
}
Dog.prototype = Object.create(Animal.prototype); // 设置继承关系
// 新的方式
class Animal{
constructor(type, name){
this.type = type;
this.name = name;
}
intro(){
console.log(`I am ${this.type}, my name is ${this.name}`)
}
}
class Dog extends Animal{
constructor(name){
super('狗', name); // 调用父级构造函数
}
}
以上。