《无所不能的JavaScript:ES6入门》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,如需交流,欢迎留言评论。👍

写在前面的话

前文《前端攻城狮 · 从 Nuxt 前端框架开篇》提到,前端技术栈正在发生翻天覆地的变化,各类新技术层出不穷,但回归基础依然是HTML+CSS+JavaScript,其中负责逻辑交互的JavaScript,我原称之为前端技术的灵魂。
后端程序猿如果想往全栈工程狮发展,那JavaScript必须和Java玩得一样明白,接下来系列文章,带你一起探索,无所不能的JavaScript。本系列第一回,就先从ES6开始说起。

旁白:JavaScript一度被认为是一种玩具编程语言,它有很多缺陷,所以不被大多数后端开发人员所重视。但这是完全错误的理解。JavaScript确实很容易上手,学习性价比高,稍微掌握一点JS基础知识,外加HTML和CSS,就可以做一个简单网页或者拿来应聘一份可以糊口的工作。但其精髓却不为大多数开发人员所熟知,如果想精通JS,使用JS进行随心所欲地编程,编写高质量的JavaScript代码更是难上加难。

ES6 技术简介

【技术简介】
ECMAScript ,是由网景公司制定的一种脚本语言的标准化规范;最初命名为 Mocha ,后来改名为 LiveScript ,最后重命名为 JavaScript。
ECMAScript 2015(ES2015),第 6 版,最早被称作 ECMAScript 6(ES6),添加了新的特性。

Tips:很多ES6用法的浏览器兼容性不强,Vue等项目开发中,是借助 Babel,用来把 ES6 的代码转化为浏览器或者其它环境支持的代码。

【块级作用域 - let】
什么是作用域?作用域简单讲就是声明一个变量,这个变量的有效范围,在 let 没来之前。js 只有 var 的全局作用域和 函数作用域 ,ES6 为 js 带来了块级作用域。

Tips:一句话,能用let尽量用let,作用域就认准大括号即可。
Tips:let 还有其他知识点(变量提升、暂时性死区等),但用的场景不多,不需要深究。

【常量修饰符 - const】
const 声明一个只读的常量。一旦声明,常量的值就不能改变。
使用 const 关键字定义常量,const 限制的是给常量分配值的动作,并不限制常量中的属性值。

Tips:修改内部的东西不报错,仅有赋值报错。
Tips:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

const app = ['☃️', '🌈'];
console.log(...app);
app.push('🤣');
console.log(...app);
app = 10;

//输出
☃️ 🌈
☃️ 🌈 🤣
TypeError: Assignment to constant variable.

//如果真的想将对象冻结,应该使用Object.freeze方法。
const foo = Object.freeze({});
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;

【判断字符串里是否包含】
使用这些函数,可以轻松的完成是不是以什么开头的字符串,是不是以什么结尾的字符串,是不是包含了什么字符串等的操作。

let str = '你好,我是小周 ❤️';
console.log(str.startsWith('你好'));
console.log(str.endsWith('你好'));
console.log(str.includes(" "));

【函数的默认参数】
ES6里,可以使用默认参数,当调用函数时,没有给参数进行赋值时,就使用设置的默认参数执行,当给参数赋值时,就会使用新赋的值执行,覆盖默认值,使用如下:

function say(str) {
    console.log(str);
}
function say1(str = '嘿嘿') {
    console.log(str);
}
say();
say1();
say1('❤️');

【对象属性名】
使用点定义对象属性时,如果属性名中含有空格字符,是不合法的,语法通不过的,使用 [属性名] 可以完美解决,并且不仅可以直接写明属性名,还可以使用变量来指定,具体使用如下:

let obj = {};
let a = 'little name';
obj.name = '王子';
// 使用点定义属性中间有空格是不合法的
// obj.little name = '小王子';
obj[a] = '小王子';
console.log(obj);

//输出
{ name: '王子', 'little name': '小王子' }

【判断两个值是否相等】
一些特殊值使用 === 或 == 进行比较的结果,可能不满足你的需求,这是你可以使用Object.is(第一个值,第二个值) 来进行判断,可能你就开心的笑了。

Tips:类似于精确等于符号 ===

console.log(NaN == NaN); //false
console.log(+0 == -0); //true
console.log(Object.is(NaN, NaN)); //true
console.log(Object.is(+0, -0)); //false

ES6 对象&数组解构

描述:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

Tips:这点日常开发中比较常用,例如export和import的场景。

【数组解构】
如下所示,首先定义了一个函数,返回一个数组,在未使用解构数组前,调用数组并把返回值赋值给 temp ,然后打印 temp 数组,使用了解构数组后,直接定义一个数组变量,然后将函数返回值指向该变量,他会自动把第一项的值赋值给第一个数组变量,第二项赋值给第二个数组变量,以此类推,最后打印三个变量,看到没有问题。

function breakfast() {
    return ['🍉', '🍔', '🍕'];
}
var temp = breakfast();
console.log(temp[0], temp[1], temp[2]);

let [a, b, c] = breakfast();
console.log(a, b, c);

//输出
🍉 🍔 🍕
🍉 🍔 🍕

//解构赋值允许指定默认值。
//注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。
//所以,只有当一个数组成员严格等于undefined,默认值才会生效。
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
let [x = 1] = [null]; //x值为null

【对象解构 - 常用】
描述:对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
示例:首先 breakfast 函数返回一个对象,使用解构对象,定义对象,键值对中键表示映射的实际对象的键名,值就是自定义变量,解构完成,会自动完成赋值,然后调用 breakfast 函数,返回对象,随后打印变量 a,b,c ,可以看到没问题。

function breakfast() {
    return { a: '🍉', b: '🍕', c: '🍔' }
}
//let { a: a, b: b, c: c } = breakfast();
let { a, b, c } = breakfast();
console.log(a, b, c);

//输出
🍉 🍔 🍕

【对象简写】
使用ES6的对象表达式,如果对象属性和值一样,可以省略值,函数写法可以省去function,用法如下:

let a = '㊙️';
let b = '☃️';
const obj = {
    a: a,
    b: b,
    say: function () {
    }
}
const es6obj = {
    a,
    b,
    say() {
    }
}

ES6 模板字符串

**前言:**ES6引进的模板字符串功能主要是为了解决原来多行字符串拼接的麻烦,以及提供变量解析的功能。
**语义:**使用反引号 (`) 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来。
示例:

var name = '123';
var desc = 'ccc';
var html = `公司名:${name}
    简介:${desc}`;

Tips:不同于普通字符串,模板字符串还可以多行书写,模板字符串中所有的空格,新行,缩进都会原样的输出在生成的字符串中。单纯的模板字符串还存在着很多的局限性,可以搭配标签模板使用。


ES6 箭头函数

提问:Vue中的 render: h => h(App) 具体是什么含义

=> 是ES6的箭头语法。
使用箭头函数可以让代码更简洁,但是也要注意箭头函数的局限性,以及箭头函数中自身没有 this,this指向父级。

let f1 = a => a;
let f2 = (a, b) => {
    return a + b;
}
console.log(f1(10));
console.log(f2(10, 10));

//输出
10
20

ES6 对象拷贝

方法一: Object.assign()

// 对象浅拷贝, 复制所有可枚举属性
const obj1 = {a: 1};
const obj2 = {b: 2};
// copy obj1 and obj2 to a new obj;
Object.assign({}, obj1, obj2)

方法二 :Res参数

//等同于方法一, 属于对象浅拷贝
const obj1 = {a: 1, b: 2};
// obj2 equal obj1
const obj2 = {...obj1};

方法三:序列化

//在对象的拷贝方法中比较困扰的就是深层拷贝,此方法为深层拷贝;
function deepCopy (data) {
  return JSON.parse(JSON.stringify(data));
}

ES6 展开&剩余操作

展开操作符
使用 … 可以展开元素,方便操作,使用如下:

Tips:主要用于数组元素,可以把数组拆分成多个子字符串。

let arr = ['❤️', '😊', '😍'];
console.log(arr);
console.log(...arr);
let brr = ['王子', ...arr];
console.log(brr);
console.log(...brr);

[ '❤️', '😊', '😍' ]
❤️ 😊 😍
[ '王子', '❤️', '😊', '😍' ]
王子 ❤️ 😊 😍

ES6 剩余操作符
… 操作符用在函数参数上,接收一个参数数组,使用如下:

Tips:类似Java的可变参数。

function f1(a, b, ...c) {
    console.log(a, b, c);
    console.log(a, b, ...c);
}
f1('🍎','🌈','☃️','㊙️');

🍎 🌈 [ '☃️', '㊙️' ]
🍎 🌈 ☃️ ㊙️

ES6 Map 和 Set

ES6 Map 用法
Map结合存储键值对,类似Java的Map,但方法名略有不同。

let food = new Map();
let a = {}, b = function () { }, c = "name";

food.set(a, '🍉');
food.set(b, '🥪');
food.set(b, '🥪');
food.set(c, '米饭');

console.log(food);
console.log(food.size);
console.log(food.get(a));
food.delete(c);
console.log(food);
console.log(food.has(a));

food.forEach((v, k) => {
    console.log(`${k} + ${v}`);
});
food.clear();
console.log(food);

//输出
Map(3) { {} => '🍉', [Function: b] => '🥪', 'name' => '米饭' }
3
🍉
Map(2) { {} => '🍉', [Function: b] => '🥪' }
true
[object Object] + 🍉
function () { } + 🥪
Map(0) {}

ES6 Set 用法
Set 集合,与数组不同,Set 集合中不允许有重复元素,与Java的Set类似。

// 创建Set集合
let food = new Set('🍎🥪');
// 重复添加,只有一个能进去
food.add('🍉');
food.add('🍉');

console.log(food);
// 当前集合大小
console.log(food.size);
// 判断集合中是否存在某一元素
console.log(food.has('🍉'));
// 删除集合中某一元素
food.delete('🥪');
console.log(food);
// 循环遍历集合
food.forEach(f => {
    console.log(f);
});
// 清空集合
food.clear();
console.log(food);

//输出
Set(3) { '🍎', '🥪', '🍉' }
3
true
Set(2) { '🍎', '🍉' }
🍎
🍉
Set(0) {}

ES6 类与实例

Tips:越来越像Java了哦。

ES6 static
使用static关键字修饰的方法,不用实例化对象也可以直接使用

class stu {
    static say(str) {
        console.log(str);
    }
}
stu.say("~~");

ES6 extends
使用继承,可以减少代码冗余,比如:

class Person {
    constructor(name, bir) {
        this.name = name;
        this.bir = bir;
    }
    showInfo() {
        return '姓名:' + this.name + '生日:' + this.bir;
    }
}
class A extends Person {
    constructor(name, bir) {
        super(name, bir);
    }
}
let zhouql = new A("周棋洛", "2002-06-01");
// 周棋洛本身是没有showInfo方法的,是继承自Person的
console.log(zhouql.showInfo());

ES6 模块化

【简单说明】
使用模块化开发,ES6可以方便的导入和导出一些内容,还有默认导出等等细节。

Tips:其实就 export、export default、import的用法,也不难。

let a = '🍉';
let f1 = function (str = '你丫的写参数') {
    console.log(str);
}
export { a, f1 };

import {a, f1} from './27模块测试.js';
console.log(a);
f1();
f1('知道了');

【实际测试】

/**
 * export 命令能够对外输出的就是三种接口:函数(Functions), 类(Classes),var、let、const 声明的变量(Variables)。
 */
//方式一
export var firstName = 'Lin';

//方式二
const lastName = 'Wang';
export { lastName };

//导出函数
export function testSum(x, y) {
    return x + y;
}

//导出并指定别名
function testConsole(x) {
    console.log(x);
}
export {
    testConsole as lwConsole
}

//导出默认
export default testConsole

/**
 * 1、import命令具有提升效果,会提升到整个模块的头部,首先执行,因此代码位置不一定要在最上方
 * 2、import语句会执行所加载的模块,因此可以有下面的写法,import 'lodash'
 * 3、模块的整体加载可以使用*和as实现
 */
import {firstName, lastName, lwConsole, testSum as lwSum} from '../test/demo1'
import * as Demo1 from '../test/demo1'
import testConsole from "../test/demo1";
import '../test/demo3'

mounted() {
  console.log('###ES6测试:普通导入导出###', firstName, lastName);
  lwConsole('###ES6测试,导出指定别名###')
  testConsole('###ES6测试,导出default方式###')
  console.log('###ES6,导入指定别名测试###', lwSum(1, 2))
  console.log('###ES6测试,导入使用*的方式###', Demo1.firstName)
},


总结陈词

上文简单介绍了ES6的基础用法,算是一个JavaScript系列入门,后续会更新更多内容。
关于ES6的更多用法,也可以参考《阮一峰 - ES6》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

战神刘玉栋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值