1. const 与 let 变量
let
与const
声明的变量解决了这种问题,因为他们是块级作用域, 在代码块(用{}
表示)中使用let
或const
声明变量, 该变量会陷入暂时性死区直到该变量的声明被处理。
关于使用let与const规则:
使用let声明的变量:可以重新赋值,但是不能在同一作用域内重新声明
使用const声明的变量:必须赋值初始化,但是不能在同一作用域类重新声明也无法重新赋值.
2. 模板字符串
可以使用反引号(``),键盘数字1左面的那个键。来定义一个字符串模板,在其中可以使用${}
来存放一个变量或者表达式。
3. 字符串新增的一些方法
{
let str = 'imshusheng.com';
// 查看字符串中是否包含某些字符
console.log(str.includes('.'));
console.log(str.includes('shu'));
//查看字符串是否以某个字符串开头
console.log(str.startsWith('i'));
console.log(str.startsWith('im'));
//查看字符串是否以某个字符串结尾
console.log(str.endsWith('com'));
console.log(str.endsWith('m'));
//字符串重复3遍
console.log(str.repeat(3))
//如果字符串的长度不满20位,则在其后面补字符s
console.log(str.padEnd(20, 's'));
//如果字符串的长度不满20位,则在其前面补字符s
console.log(str.padStart(20, 's'));
}
4. 函数
4.1 默认参数
之前的js中, 我们是无法像python、php等语言一样给函数的形参指定默认参数的,我们一般这样解决问题。
function xxx(a, b) {
b = b || 100;
console.log(a);
console.log(b);
}
xxx(1)
在ES6中,我们可以这样做了:
function xxx(a, b = 100) {
console.log(a);
console.log(b);
}
xxx(1)
4.2 可变数量参数
// 使用可变数量参数可以接受任意数量的参数
// 可变数量参数之后不能再有形参
function xxx(z, ...argues) {
console.log(z);
console.log(argues);
}
xxx(22, 'imshusheng.com', 44, 66)
4.3 箭头函数
箭头函数是ES6中新增的一个十分重要的内容,它的组成结构是这样的:
函数名 = 参数 => 返回值的表达式
比如我们可以这样定义函数:
// 定义一个getSex函数
getSex = num => num === 0 ? '女' : '男';
// 调用函数
console.log(getSex(1));
console.log(getSex(0));
多个参数或者无参数的时候,需要用括号包着形参:
// 无参数的时候使用个空括号占位
getSex = (num, say) => `${say} 是 ${num === 0 ? '女' : '男'}的`;
console.log(getSex(1, '小明'));
console.log(getSex(0, '小花'));
如果函数体内需要有多条语句时,它的结构是这样的:
函数名 = 参数 => 函数体
getSex = (num, say) => {
let sex;
if (num === 0 ){
sex = '女';
}else{
sex = '男'
}
//需要手动返回
return `${say} 是 ${sex}的`;
};
console.log(getSex(1, '小明'));
console.log(getSex(0, '小花'));
5. 解构赋值
在ES6中,可以使用解构从数组和对象提取值并赋值给独特的变量
5.1 解构数组
var a = ['大哥', '二哥', '三弟'];
[x, y ,z] = a;
console.log(x);
console.log(y);
console.log(z);
[]
表示被解构的数组, x
,y
,z
表示要将数组中的值存储在其中的变量, 在解构数组是 还可以忽略值, 例如var [x, , z] = a
,忽略第二个值。
{
let a = ['大哥', '二哥', '三弟', '四弟', '五弟'];
// 如果解构时, 某个变量前面使用三个点,表示将后面解构出来的内容都给该变量
[x, y ,...z] = a;
console.log(x);
console.log(y);
console.log(z);
}
var a = ['大哥', '二哥', '三弟'];
// 如果解构的变量过多, 没有被分配的变量的值为 undefined
[x, y , z, xx] = a;
console.log(x);
console.log(y);
console.log(z);
console.log(xx);
var a = ['大哥', '二哥', '三弟'];
// 解构的变量也可以有默认值
[x, y , z='三儿', xx='小妹'] = a;
console.log(x, y, z, xx);
5.2 解构对象
var a = {
name: '张三',
age : 18,
sex : '男'
};
var {name, age ,sex} = a;
console.log(name, age, sex);
6. 数组新增方法
{
// 将几个值转成数组
let a = Array.of(1, 3, 5, 7, 9);
console.log(a)
// 将集合等数据类型转成数组
let b = new Set([1, 3, 5, 7, 9]);
console.log(b);
console.log(Array.from(b));
// 将数组中的值替换成我们设置的值
let d = ['a', 'b', 'c', 'd', 'e'];
console.log(d.fill(100));
console.log(d.fill(101, 2));
console.log(d.fill(102, 2, 3));
}
let e = ['a', 'b', 'c', 'd', 'e'];
//之前遍历数组
for (let i in e){
console.log(i)
}
//es6 中新增的几种遍历数组方式
for (let i of e){
console.log(i)
}
for (let i of e.keys()){
console.log(i)
}
for (let i of e.values()){
console.log(i)
}
for (let [i, j] of e.entries()){
console.log(i, j)
}
let f = [1, 3, 5, 7, 9];
// find 会将数组的每一个元素放入到函数中进行迭代处理
// 将第一个满足条件的值取出来
console.log(f.find(function (x) {
return x > 5
}));
// findIndex 会将数组的每一个元素放入到函数中进行迭代处理
// 将第一个满足条件的值的键取出来
console.log(f.findIndex(function (x) {
return x > 5
}));
// 检验某个值是否在数组内
console.log(f.includes(5))
7. 面向对象
7.1 类的创建
我们在ES6之前,我们是通过构造函数创建对象的,也就是说,其实构造函数就是我们的类。
function Human(name, sex) {
this.name = name;
this.sex = sex;
//私有成员
var friend = '小美';
this.say = function () {
console.log('我的朋友是', friend)
}
}
var h1 = new Human('大海', '男');
console.log(h1);
h1.say()
在ES6中,给我们提供了一种语法糖(底层实现和es5一样),我们可以通过class
关键字更优雅的创建和使用类以及对象:
/**
* 定义一个Human类
* 类中的所有成员对外都是可见的,即没有私有成员
* 使用该方式创建类的成员方法,前面不能用 function 修饰
*/
class Human{
//这是构造方法, 名字必须叫 constructor
constructor(name, sex){
this.name = name;
this.sex = sex;
}
//类的一个普通的成员方法
say(){
console.log(`我的名字是${this.name}`)
}
}
var p2 = new Human('张三', '女');
p2.say();
console.log(p2.sex)
7.2 类的继承
/**
* 定义一个父类
*/
class Human{
//这是父类构造方法
constructor(name, sex){
this.name = name;
this.sex = sex;
}
//父类的一个普通的成员方法
say(){
console.log(`我的名字是${this.name}`)
}
}
/**
* 定义一个Student类,该类继承于Human类
*/
class Student extends Human{
//子类的构造函数
constructor(name, sex){
//super当函数使用的时候表示:调用父类的构造函数
super(name, sex);
// 子类扩展自己的属性,必须要放到super调用之后
this.score = 100
}
// 子类中的方法
run(){
console.log(`${this.name}跑的真快,搞得我都没看出他是${this.sex}的`)
}
}
let p3 = new Student('小明', '男');
p3.run()
7.3 setter
和getter
getter 是一种获得属性值的方法,setter是一种设置属性值的方法。
一定注意,他们针对的是类的属性,并不是方法。
class Human{
//这是构造方法, 名字必须叫 constructor
constructor(name, sex){
this.name = name;
this.sex = sex;
}
// 如果通过对象设置xxx属性值的时候,会自动调用这个方法
set xxx(x){
console.log('setter被调用了');
this._xxx = x
}
// 如果通过对像获取xxx属性值的时候,会自动调用这个方法
get xxx(){
console.log('getter被调用了');
return this._xxx
}
}
var h2 = new Human('小花', 18);
// 读取xxx属性的值
console.log(h2.xxx);
//设置xxx属性的值
h2.xxx = '大海';
// 读取xxx属性的值
console.log(h2.xxx);
从上面我们可以看出,虽然我们的xxx
在定义的时候,是个方法,但是我们使用的时候,其实是把它当成属性用的。
推荐一本书:
https://github.com/getify/You-Dont-Know-JS/tree/1ed-zh-CN