JS基础:ES6关于基本语法的一些扩展

目录

一. 解构赋值
 1. 数组的解构赋值
 2. JS对象的解构赋值
 3. 解构赋值的应用场景
二. 字符串的扩展
 1. 模板字符串
三. 数组的扩展
 1. 扩展运算符...
四. JS对象的扩展
 1. 扩展运算符...
五. 函数的扩展
 1. 箭头函数


一. 解构赋值


所谓解构赋值,是指当我们需要批量地从一个数组或字典中读取数据赋值给一堆指定的变量时采用的赋值方法,这种方法是ES6提供的,要比我们平常使用的赋值方法简便一些。

它的使用方式也很简单,我们只需要保证等号左边被赋值的一堆变量和等号右边的数组或字典的格式一样就行了。

1. 数组的解构赋值

比如说我们现在有一个数组arr,里面存放好了要用的数据,现在要从数组中读取数据赋值给指定的变量。

在ES5中,我们通常的做法会像下面这样。

let arr = [1, 2, 3, 4, 5];

let a = arr[0];
let b = arr[1];
let c = arr[2];
let d = arr[3];
let e = arr[4];

// a = 1
// b = 2
// c = 3
// d = 4
// e = 5

我们发现,如果只是从数组中读取少量的数据赋值给指定的变量还好,可以一个一个地写,但是如果数据量很大,一个一个写就很头疼了,遍历倒是可以省劲,但是无法达到把数据赋值给指定的变量的效果,这时候ES6的解构赋值就派上用场了。

let arr = [1, 2, 3, 4, 5];

let [a, b, c, d, e] = arr;

// a = 1
// b = 2
// c = 3
// d = 4
// e = 5

下面是一些别的例子。

let arr = [1, 2, 3, 4, 5];
let [a, , c, , e] = arr;
// a = 1
// c = 3
// e = 5


let arr = [1, 2, 3, 4, 5];
let [a, b, c] = arr;
// a = 1
// b = 2
// c = 3


let arr = [1, 2, 3, 4, 5];
let [a, b, c, d, e, f] = arr;
// a = 1
// b = 2
// c = 3
// d = 4
// e = 5
// f = undefined


let arr = [1, [2, 3, 4], 5];
let [a, [b, c, d], e] = arr;
// a = 1
// b = 2
// c = 3
// d = 4
// e = 5

2. JS对象的解构赋值

JS对象的解构赋值和数组的解构赋值在本质上当然是一样的,不同的就是数组的元素是有序的,给变量赋值的时候按着顺序赋值就行了,而JS对象的元素是无序的,所以要赋值的变量名必须和JS对象里的属性名一样才能赋值成功。

比如说现在有一个person对象,我们要从中读取数据赋值给指定的变量,那我们就知道变量名一定要取的和person对象的属性名一样。

在ES5里,我们会这样做。

let person = {
    'name': '张三',
    'sex': '男',
    'age': 11 
};

let personName = person.name;
let personSex = person.sex;
let personAge = person.age;

// personName = "张三"
// personSex = "男"
// personAge = 11

这种单个读取单个赋值的方式,变量的名字可以随便取,但如果使用ES6里的解构赋值,那变量名就必须于JS对象的属性名一样,变量的顺序倒是无关紧要。

let person = {
    'name': '张三',
    'sex': '男',
    'age': 11 
};

let {sex, age, name} = person;

// name = "张三"
// sex = "男"
// age = 11

简单好些吧,不过注意变量名就不需要加''了哦,你见过谁家变量名加引号的。

下面是一些别的例子。

let person = {
    'name': '张三',
    'sex': '男',
    'age': 11 
};
let {sex, name} = person;
// name = "张三"
// sex = "男"


let person = {
    'name': '张三',
    'sex': '男',
    'age': 11 
};
let {sex, age, name, height} = person;
// name = "张三"
// sex = "男"
// age = 11
// height = undefined


// 嵌套对象的解构赋值
let obj = {
  p: [
    'Hello',
    {y: 'World'}
  ]
};
let {p, p: [x, {y}]} = obj;
// p = ["Hello", {y: "World"}]
// x = "Hello"
// y = "World"

3. 解构赋值的应用场景

  • 交换两个变量的值
let a = 1;
let b = 2;

[a, b] = [b, a];

// a = 2
// b = 1

很爽吧。

  • 提取JSON数据

这是解构赋值最常用的一个场景,比如我们从网络上请求到了JSON数据,用解构赋值很方便。

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let {id, status, data} = jsonData;

// id = 42
// status = "OK"
// data = [867, 5309]


二. 字符串的扩展


1. 模板字符串

模板字符串是增强版的字符串,用反引号``来标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串里插入变量。

ES6之前,我们定义一个字符串用的是单引号''

let str = 'if i see her standing there alone';

str;// "if i see her standing there alone"

ES6之后,我们也可以用模板字符串来定义一个字符串。

let str = `if i see her standing there alone`;

str;// "if i see her standing there alone"

ES6之前,如果我们想定义一个多行字符串,那就需要在每个换行的地方手动插入\n

let str = 'if i see her standing there alone \n at the train station three stops from her home \n i have half a mind to say what i’m thinking anyway \n i don’t know \n i don’t know';

str;//
"if i see her standing there alone 
 at the train station three stops from her home 
 i have half a mind to say what i’m thinking anyway 
 i don’t know 
 i don’t know"

ES6之后,我们用模板字符串可以直接在需要换行的地方,敲击换行就可以了。(我们搞多行字符串有可能是为了开发人员看起来清晰舒服,毕竟如果一个字符串很长,一眼都看不到尾,我们可能会采用分段字符串,然后用+连接,这样看起来舒服点。也有可能是我们要把这个带换行的字符串传给后台,那就得用\n。但是有了模板字符串,这一切开发操作都变得更舒服更爽了。)

let str = `if i see her standing there alone
at the train station three stops from her home
i have half a mind to say what i’m thinking anyway
i don’t know
i don’t know`;

str;//
"if i see her standing there alone 
 at the train station three stops from her home 
 i have half a mind to say what i’m thinking anyway 
 i don’t know 
 i don’t know"

ES6之前,如果一个字符串里有很多变量,那我们就得用很多个加号+(字符串连接符)把常量和变量连接起来,同时还需要注意字符串里的逗号啊、空格啊等格式不能给人家少掉,有一点麻烦呢。

let name = 'Mary';
let sex = 'female';
let age = 25;
let str = 'hi, my name is ' + name + ', ' + sex + ', ' + age + ' years old';

str;// "hi, my name is Mary, female, 25 years old"

ES6之后,用模板字符串可以很方便地在字符串中插入变量,我们只需要用${}把变量包起来,然后直接把变量插入到相应的位置就可以了。

注意:

模板字符串里插入的这个变量最终肯定是个字符串,但写代码时你可以传进去任意JS数据类型,不要担心,运行时都会给你转化为字符串的,你甚至可以在${}调用一个函数,但这个函数最好有一个字符串作为返回值,否则这么做没什么意义。

let name = 'Mary';
let sex = 'female';
let age = 25;
let str = `hi, my name is ${name}, ${sex}, ${age} years old`;
str;// "hi, my name is Mary, female, 25 years old"


function fun() {
    1 + 1;
}
let str = `hi, my name is ${fun()}`;
str;// "hi, my name is undefined"


function fun(name) {
   return name;
}
let str = `hi, my name is ${fun('Mary')}`;
str;// "hi, my name is Mary"


三. 数组的扩展


1. 扩展运算符...

数组的扩展运算符...用来将数组打散为一个用逗号分隔的参数序列,这是一个非常有用的扩展,比如我们给一个数组从另一个数组批量添加数据时会用到,给函数传多个参数时也会用到。

console.log(1, [2, 3, 4], 5);// 1 [2, 3, 4] 5

console.log(1, ...[2, 3, 4], 5);// 1 2 3 4 5

扩展运算符可以用来实现数组的深拷贝(值拷贝,指向不同的对象)。

JS里,数组的直接赋值是一个浅拷贝(指针拷贝,指向同一个对象)。

let arr1 = [1, 2];
let arr2 = arr1;

arr2[1] = 1;

arr1;// [1, 1]
arr2;// [1, 1]

而如果我们想要实现数组的深拷贝就可以通过扩展运算符来实现。

let arr1 = [1, 2];
let arr2 = [...arr1];

arr2[1] = 1;

arr1;// [1, 2]
arr2;// [1, 1]


四. JS对象的扩展


1. 扩展运算符...

JS对象的扩展运算符...用来将JS对象打散为一对一对key-value的参数序列。

let obj = {
    'name': '张三',
    'sex': '男',
    'age': 11
};

let newObj = {
    ...obj,
    'height': 177,
    'weight': 67
};

newObj;// {name: "张三", sex: "男", age: 11, height: 177, weight: 67}

以上newObj除了heightweight属性之外,其它的属性均来自被打散了的obj对象。

扩展运算符可以用来实现JS对象(字典)的深拷贝(值拷贝,指向不同的对象)。

JS里,JS对象的直接赋值是一个浅拷贝(指针拷贝,指向同一个对象)。

let obj = {
    'name': '张三',
    'sex': '男',
    'age': 11
};
let newObj = obj;

newObj.name = '李四';

obj;// {name: "李四", sex: "男", age: 11}
newObj;// {name: "李四", sex: "男", age: 11}

而如果我们想要实现数组的深拷贝就可以通过扩展运算符来实现。

let obj = {
    'name': '张三',
    'sex': '男',
    'age': 11
};
let newObj = {...obj};

newObj.name = '李四';

obj;// {name: "张三", sex: "男", age: 11}
newObj;// {name: "李四", sex: "男", age: 11}


五. 函数的扩展


1. 箭头函数

1.1 基本用法

ES6给我们提供了一种定义匿名函数的新方法——箭头函数(注意是匿名函数哦,普通函数还是用老方法定义),它有好几个优点,如果想了解可以自己去查,总之你用就行了,箭头函数的格式为(参数) => {执行体},就这么简洁,不过注意要把分号;捋清楚。

let func = function () {
    console.log('Hello World');
};

let func = () => {console.log('Hello World');};

传统定义法如下,一个函数无非就四个部分:函数名、函数的具体实现、参数和返回值(返回值语句包含在函数体内)。

var 函数名 = function(参数1, 参数2, ...) {

    // 函数的具体实现
}

那么用箭头函数=>来定义函数的话,无非也包含这四个部分就可以了嘛,箭头函数的标准写法就是:(函数参数) => {函数体};,要是给一个变量赋值的话就是:var 函数名 = (函数参数) => {函数体};,但是也有变种,例如:当我们参数只有一个时,我们可以省略掉函数参数部分的(),同时如果我们省略了函数体部分的{},那么箭头函数是会默认把=>后面表达式的值作为函数的返回值。

var f = function(param) {
    return param;
}

标准写法

var f = (param) => {return param};

等价于

var f = param => param;

需要特别注意的是:

箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。即this对象的指向是可变的,但是在箭头函数中,它是固定的。

当然也正是因为箭头函数里的this由动态变为静态的了,所以需要动态this的场合我们就不能使用箭头函数。

因此:
写箭头函数或分析别人写的箭头函数是什么意思,首先要把箭头函数分为三部分:参数、=>=>后面的返回值或执行体

特别要注意的是,如果=>后面没有写{},就代表该箭头函数的真正执行体为执行这段代码,并把代码执行的结果作为该箭头函数的返回值返回,如果=>后面写了{},那该箭头函数的执行体自然就是我们自己写的这段代码了。

注意,箭头函数只是一个匿名函数,别看它的样子像立即执行就觉得它会立即执行,它和匿名函数一样,除非你定义了立马调用它,它才会立即执行,否则就是定义了一个函数而已。因此

var f = (param) => {return param};

我们是给f赋值了一个匿名函数嘛,因此它永远是个函数,我们不通过f()调动这个函数,右面的箭头函数就不可能执行,所以千万不要以为f会等于return回来的param,除非直接让箭头函数执行才是这样。

var f = (() => {return 123})();
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容

  • [TOC] 参考阮一峰的ECMAScript 6 入门参考深入浅出ES6 let和const let和const都...
    郭子web阅读 1,773评论 0 1
  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    呼呼哥阅读 3,364评论 0 1
  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    陈老板_阅读 447评论 0 1
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 2,892评论 0 16
  • 1、春季空气干燥,早晚温差大,皮肤会流失大量水分,容易起皮和翘皮,应做好皮肤的补水工作; 2、隔离防护乳可以很好的...
    石竹阅读 528评论 4 2