ES6(ECMAScript 6)常用新特性

ECMAScript 6.0,是JavaScript的下一个标准版本,ECMAScript是JavaScript的语言规范(标准),JavaScript是ECMAScript的实现和扩展,ECMAScript 6.0发布于2015年6月,成为国际标准。

1、块级作用域

这个是ES6中新增的一个作用域,之前的版本中只有全局作用域和函数作用域,那么什么是块级作用域呢? {}中间的内容就是属于块级作用域,比如我们常见的forifwhile 等语句,首先在es6的块级作用域中,没有内层变量覆盖外层变量的现象:

var a = "外层变量"

function test1() {
    console.log(a) // 外层变量
}

// var会变量提升,提升到函数的最上面,就相当于现在函数中声明了a
// 然后在if中初始化了a,需要注意的是,变量提升只提升声明,不提升初始化
function test2() {
    console.log(a) // undefine
    if (false) {
        var a = "内层变量"
    }
    console.log(a) // 输出 undefine(若上面的if条件是true的话则输出 内层变量)
}

// let不会变量提升,所以函数内的a只在if中有效果
function test3() {
    console.log(a) // 外层变量
    if (false) {
        let a = "内层变量"
    }
    console.log(a) // 外层变量
}

而且不存在变量泄漏为全局变量的现象:

if (true) {
    var a = "内层变量"
}
console.log(a) // 内层变量

if (true) {
    let b = "内层变量"
}
console.log(b) // Error: b is not defined

此外,还允许在块级作用域内声明函数,而且也存在函数变量提升的现象:

if (true) {
    
    test() // test
    
    function test() {
        console("test")
    }
}

内层作用域声明的同名函数不干扰外层作用域的同名函数:

if (true) {

    test() // 外层函数
    
    if (true) {
    
        test() // 内层函数
        
        function test() {
            console("内层函数")
        }
    }
    
    function test() {
        console("外层函数")
    }
    
    test() // 外层函数
}

2、var、let和const

说完了块级作用域,我们再来看这几个定义变量的关键字,首先let和const是es6才出的新的关键字,这几个关键字的主要区别就是在不同作用域内是否可以访问,具体来看一下代码:

for (var i = 0; i < 10; i++) {
    console.log(i) // 0,1,2...9
}
console.log(i) // 10

for (let i = 0; i < 10; i++) {
    console.log(i) // 0,1,2...9
}
console.log(i) // Error:i is not defined

这就是var和let的区别,var可以跨块级作用域访问,而let没有这样的功能,只能在当前块级作用域内使用,但是两者均不能垮函数作用域访问,而const一般用来定义常量,使用时必须初始化,和let一样只能在当前块级作用域内使用,并且不能修改(一般情况下),原则上用const定义的常量是不能修改的,但是如果用const定义一个对象,这时候对象里面的内容是可以修改:

const user = {
    name: "24K纯帅",
    sex: 0
}

user.sex = 1

console.log(user.sex)  // 输出1

// 下面会报错
user = {
    name: "小明",
    sex: 1
}

这是因为对象是引用类型,并且user中仅保存对象的指针,而const仅保证指针不发生改变,修改对象属性是不会改变对象的指针,所以上述操作修改性别是允许的;后面重新给user对象赋值,这就直接改变了对象的指针,所以会报错。

3、模板字符串

ES6之前传统的JS模版输出采用 “+” 连接,ES6开始支持反引号标识(`),既可以当做普通字符串使用,也可以在字符串中嵌套变量来使用:

var a = `I am 24K纯帅`

var b = `Hi! ${a}`

4、变量的解构赋值

先来看一个简单的例子,假如我有一个对象,我要取出对象中的值,最简单的方法就是:

var data = { name: '24K纯帅', sex: '1', province: '浙江', city: '杭州' }
var name = data.name
var sex = data. sex
var province = data.province
var city = data.city

在ES6之前,我们会采用上面的方法将对象中的值取出,这样看来是比较繁琐的,ES6中新增了变量的解构赋值,使用这种方式能够很快捷的取出我们想要的值:

// 全部取出
const { name, sex, province, city } = { name: '24K纯帅', sex: '1', province: '浙江', city: '杭州' }

// 按需取出
const { name, sex, city } = { name: '24K纯帅', sex: '1', province: '浙江', city: '杭州' }

就是这么简单,不仅仅是对象,数组也是同样适用,需要注意的是进行对象解构赋值时需要将变量名与之对应上,这样才能取到你要的值,数组是根据下标来取的,如果超出数组长度的话不会报错,取出来的值就是undefine

5、函数

(1)、参数默认值

在ES6之前,函数不能直接指定函数参数默认值,只能通过在函数内进行判断的方式来给默认值,比如:

function log(x, y) {
    y = y || '默认值'
    console.log(x, y)
}

一个很简单的打印的例子,当调用者传入一个x时,此时y是有一个默认值的,但是当用户传的y是一个空字符串时,此时y也会变成默认值,这样就存在一个弊端;在ES6之后,函数提供参数可以设置默认参数,直接在函数参数声明的地方即可:

function log(x, y = '默认值') {
    console.log(x, y)
}
log('1', undefined)

这样就保证你传入的y如果不是undefined的话,那么就会使用传入的y,如果传入的y是undefined,那么也会使用默认值;这样设置默认参数的第二个好处是,调用者一眼就可以看出哪些参数是可以不用传省略的。

(2)、箭头函数

在ES6中,允许使用 "=>" 箭头来定义函数,比平常定义函数要简洁的多,比如:

// 一个参数
var f = function(v) {
    return v;
}
var f = v => v;

// 多个参数
var add = function(a, b) {
    return a + b;
}
var add = (a, b) => a + b;

// 无参数
var ff = function() {
    return 666;
}
var ff = () => 666;

如果你把箭头函数想成是简化函数的一个操作,那么就大错特错了,箭头函数的一大主要的特点就是this作用域,我们来看一个例子:

var person1 = {
    name: '24K纯帅',
    getName:function() {
        document.body.addEventListener("click", function(){
            return this.name
        }, false)
    }
}

var person2 = {
    name: '24K纯帅',
    getName:function() {
        var That = this
        document.body.addEventListener("click", function(){
            return That.name
        }, false)
    }
}

var person3 = {
    name: '24K纯帅',
    getName:function() {
        document.body.addEventListener("click", () => {
            return this.name
        }, false)
    }
}

person1.getName() // 会报错,找不到this.name
person2.getName() //正常运行
person3.getName() //正常运行

因为作用域的缘故,第一个对象中this和getName的this绑定不是同一个,所以会调用不了;然而在第二个对象中用That将this赋值了,所以That和getName的this绑定是同一个,所以可以调用到;所以这个地方就体现了箭头函数的作用了,使用箭头函数可以替代var That = this的赋值操作,让调用生效。

6、数组的扩展

比较常用的就是扩展运算符(...),该运算符通常用来复制/合并数组,怎么个复制合并呢:

复制数组:
var a1 = [1, 2]
var a2 = [...a1]

这个时候如果改变a2[0] = 2,并不会改变a1的值

合并数组:
var a1 = [1, 2]
var a2 = [3, 4]

var a3 = [...a1, ...a2] // 1, 2, 3, 4

7、==、===、Object.is()的区别

两等号是相等运算符,它会将比较的变量自动转换数据类型;三等号是严格相等运算符,Object.is()是ES6新出的,它和三等号运算符功能差不多,但是有些细微的差别;搞懂这几个的区别,从几个简单的例子开始:

'1' == 1   // true
'1' === 1  // false

[1] == 1   // true
[1] === 1  // false

{1} == 1 // 会报错

当使用双等号和数字进行比较时,会自动将非数字的一方转成数字(前提是可以转成数字的,对象{}就不能和数字进行比较)类型再来进行比较,三等号不会转换数据类型,直接比较,所以三等号比两等号快;而Object.is的比较和三等差不多,在一些细微的地方有点差别:

0 === -0  // true
Object.is(0, -0) // false

NaN === NaN  // false
Object.is(NaN, NaN)  // true

这三种比较方式都有各自不同的步骤:

(1)、===

对于x === y,该运算符的比较步骤如下:
    1、如果x的类型和y的类型不一样,返回false;
    2、如果x的类型是数字,那么:
        (1)、如果x是NaN,返回false;
        (2)、如果y是NaN,返回false;
        (3)、如果x和y是同一个数字值,返回true;
        (4)、如果x是+0,y是-0,返回true;
        (5)、如果x是-0,y是+0,返回true;
    3、返回SameValueNonNumber(x, y)的结果。
SameValueNonNumber(x, y)抽象操作比较两个非数字并且同类型的x和y是否相等,比较步骤如下:
    1、如果x的类型是null或者undefined,返回true;
    2、如果x是字符串类型,
        (1)、如果x和y是完全相同的字符编码序列,返回true,否则返回false;
    3、如果x是布尔类型,
        (1)、如果x和y同为true或者false,返回true,否则返回false;
    4、如果x是symbol类型,
        (1)、如果x和y是相同的符号值,返回true,否则返回false;
    5、如果x和y是同一个对象值,返回true,否则返回false。

(2)、Object.is()

对于Object.is(x, y),会使用抽象操作SameValue(x, y)进行比较,该抽象操作的步骤如下:
    1、如果x的类型和y的类型不一样,返回false;
    2、如果x的类型是数字,那么:
        (1)、如果x和y都是NaN,返回true;
        (2)、如果x是+0,y是-0,返回false;
        (3)、如果x是-0,y是+0,返回false;
        (4)、如果x和y是同一个数字值,返回true;
    3、返回SameValueNonNumber(x, y)的结果。

(3)、==

对于x == y,该运算符的比较步骤如下:
    1、如果x和y的类型相同,返回x === y的结果;
    2、如果x是null,y是undefined,返回true;
    3、如果x是undefined,y是null,返回true;
    4、如果x的类型是数字,y的类型是字符串,返回x == ToNumber(y)的结果;
    5、如果x的类型是字符串,y的类型是数字,返回ToNumber(x) == y的结果;
    6、如果x的类型是布尔类型,返回ToNumber(x) == y的结果;
    7、如果y的类型是布尔类型,返回x == ToNumber(y)的结果;
    8、如果x的类型是字符串、数字或者Symbol中的一种,y的类型是对象,返回x == ToPrimitive(y)的结果;
    9、如果x的类型是对象,y的类型是字符串、数字或者Symbol中的一种,返回ToPrimitive(x) == y的结果;
上面用到了方法ToNumber,ToNumber(x)的步骤如下:
    1、如果x的类型是Undefined,返回NaN;
    2、如果x的类型是Null,返回+0;
    3、如果x的类型是布尔类型,x为true返回1,false返回+0;
    4、如果x的类型是数字,返回x;
    5、如果x的类型是字符串,参考字符串转化为数字,本文不详细介绍这块内容;
    6、如果x的类型是Symbol,返回NaN;
    7、如果x的类型是对象,
        (1)、让primValue的值是ToPrimitive(x, hint Number);
        (2)、返回ToNumber(primValue)的结果;

参考

JavaScript中的==,===和Object.is()

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