ES6学习总结(一)

前言

使用ES6开发有很长一段时间了,最近看相关的一些书籍,以下是我的一些总结。

块级作用域(let、const的出现)

ES6出现之前,我们使用var关键字来声明变量经常会遇到变量提升的问题,为了解决这种问题ES6引入了块级作用域的概念。

块级作用域的创建
1、一个函数内部

function demo () { \\块级作用域 }

2、一个代码块(由一对花括号包裹)内部

function demo (param) { 
    if (param) {
	 // 块级作用域
	} else {
	 // 块级作用域
	}
 }

let声明
let的语法和var一致,区别主要在于作用域的限制上。

const声明
const声明的变量会被认为是常量(constant),一旦声明就不能被改变,需要被赋予初始值。
使用const声明对象时要注意const声明会阻止对于变量绑定与变量自身值的修改,它不会阻止变量成员自身的修改。

const obj = { name: "xiaoming" }
obj.name = 'xiaoli' //正常,只是改变了变量成员的内容
obj = { name: 'xiaoli' } // 报错,因为操作会改变变量绑定

let、const的与var的区别
1、使用let、const声明变量的作用域会被限制在当前代码块或函数内部,不会有var带来的变量提升问题。

function demo (param) { 
    if (param) {
	 let value = 'hello';
	} else {
	 // value 在这不可用
	}
	// value 在这不可用
 }

let、const声明的变量在声明处之前是无法访问的,因为此时的变量位于暂时性死区内,任何在这个区域内访问变量的操作都会导致运行错误,只有到达变量声明语句后变量才会从暂时性死区移除被正常使用。
暂时性死区是块级绑定的一个独特表现,另外在使用循环时也需要注意

if (bl) {
    console.log(value); // 报错
    let value = "hello";
}
for (let i = 0; i < 10; i++) {
    // 可使用i
}
console.log(i) // 报错

2、在相同作用域下,使用let或const重复声明一个变量会报错

let value  = "hello";
let value  = "world"; // 报错
// 不同作用域下不影响
let value1 = "hello";
if (bl) {
   let value1 = "world"; //正常使用
} 

3、在使用循环时三者也存在差异,参考以下代码

var arr = [];
for (var i = 0; i < 10; i++){
   arr.push(function(){
      console.log(i)
 })
}
arr.forEach(function(value) {
   value() // 输出十次"10"
})

var由于可以在循环作用域外访问的特点,循环体内的变量i在每次迭代中共享,也就是说每次调用数组内函数表达式的时候都调用了i的最终值10。
解决这种问题需要在每次迭代中使用函数表达式创建一个新副本

var arr = [];
for (var i = 0; i < 10; i++){
   arr.push( function (value) {
	  return function(){
	      console.log(value)
	    }
	 }(i))
}
arr.forEach(function(value) {
   value() // 依次输出十次"0-9"
})

使用let的话可以避免这个过程,let声明在循环的每次迭代中都会创建一个同名变量对其初始化。const声明类似于let声明,但是由于const声明的是一个常量,常规的for循环中试图改变它值的操作会报错例如:

for (const i = 0; i < 10; i++){
    console.log(i)
}
// 在第一次迭代后报错

在for-in、for-of、forEach中const效果同let等效

4、在全局作用域中var声明的变量会成为全局对象(window)的一个属性,会有无意间覆盖一个全局属性的风险,而let和const不会

var RegExp = "hello"
console.log(window.RegExp) // hello
let Math = "hello"
console.log(Math === window.Math) // false
const val = "hello"
console.log(val in window) //false 

字符串的扩展

字符串对象新加扩展
codePointAt()方法:在给定字符串中按位提取Unicode代码点,该方法接受的是码元位置而非字符位置,一般类似于charCodeAt()方法。
fromCodePoint()方法:codePointAt()的相反操作。
normalize() 方法:接受单个可选的字符串参数,用于指示使用那种Unicode标准形式,当比较字符串时,可以使用该方法标准化为同一种形式。
includes() 方法:在给定文本存在于字符串中的任意位置时会返回 true ,否则返回
false 。
startsWith() 方法:在给定文本出现在字符串起始处时返回 true ,否则返回 false 。
endsWith() 方法:在给定文本出现在字符串结尾处时返回 true ,否则返回 false 。
repeat()方法: 接受一个参数作为字符串的重复次数,返回一个将字符串重复指定次数的字符串。

模板字符串
模板字符串最简单的表达方式的是用两个反引号(``)包裹的字符串。如果字符串中需要使用反引号可以用/来转义

let mes = `hello\` world`  // hello` world
let str = `hello 
world`
/* hello
world
*/
// 不需要额外的/n换行符

模板字符串可以存在替换位,替换位由 ${ 开始,由 } 结束,替换位中的内容可以是一个表达式,并且替换位允许嵌套模板字符串

let name = "world"
let num = 1
let mes = `hello ${name} ${++num}`  // hello world 2
let mes1 = `${mes} repeat` // hello world 2 repeat

模板字符串可以作为参数被一个函数解析,这个函数称为模板标签,在模板字符串的起始处(即第一个`前)被指定,该函数能接收到的内容是替换位以外字符串组成的数组、替换位的解释值。

let name = "world"
let num = 1
function pass (raws,...params) {
   console.log(raws,...params)
}
pass `hello ${name} ${++num}` // ["hello ", " ", ""], "world", 2

模板字符串与以往字符串的对比
1、对多行字符串的表达方式上,模板字符串不需要添加额外的换行字符。
2、模板字符串有替换位概念,能降字符串部分替换位已经存在的变量值。
3、HTML转义方面,能转换字符串以便将其安全插入到HTML中的能力。

函数的变更

参数默认值
在ES5或者之前的版本赋给函数参数默认值需要在函数体内做额外操作,在ES6中能使用赋予初始值的形式给予参数默认值。

//ES5 及以前
function (num, str) {
      num = (typeof num !== undefined) ? num : 10 ;
      str = (typeof str !== undefined) ? str : "string";
}
//ES6
function (num = 10, str = "string"){}
// 参数默认值也可以是一个函数,该函数要注意给与返回值
function setValue(value) {
   return ++value
}
function add(first, second = setValue(first)){
   console.log(first, second)
}
add(1) // 1, 2
// 这里有一点需要注意
function add(first = second, second){}
//这种写法的默认值无法被使用,即add(undefined, 1)使用会报错,因为second被fisrt调用时存在于暂时性死区
//add(undefined, 1)等同于 let first = second ; let second = 1

剩余参数
剩余参数的引入形式是由三个点(…)与一个紧跟着的具名参数,它是一个包含除前边具名参数以后所有传入参数组成的数组,在之前我们要取函数多传的参数要用arguments对象使用ES6我们可以利用剩余参数达到我们的需求。需要注意的是一个函数只能有一个剩余参数,而且只能放在最后。

// es6 剩余参数使用方法
function test(params, ...keys){
    console.log(...keys)
}
test(1,2,3,4,5) // [2,3,4,5] 
// es6之前需要从arguments对象中寻找

函数构造器增强
ES6中允许函数构造器的能力(Function),允许使用默认参数和剩余参数。

 var add = new Function("first", "second = 1","return first + second", )
 add(1) // 2
 var add1 = new Function("first", "...rest", "return rest")
 add(1,2) // [2]

提供名称属性
ES6给所有函数提供了name属性,这里列举几种情况

function method() {}  // method.name 为 method
var othermethod = function () {} // othermethod.name 为 method1
var method = function othermethod() {} // method.name 为 othermethod
//特殊情况
//1、使用bind()创建的函数汇总名称属性前带有"bound"
var dosomething = function () {}
dosomething.bind().name // bound dosomething
//2、使用Function构造器创建的函数名称带有"anonymous"
var method = new Function()
method.name ///anonymous method

new.target属性
用于区分函数是否使用new来调用(作为构造器),相比于之前能够区分[[call]]是否被执行了,如果被执行那么new.target的值会为undefined,如果用new调用则会显示作用对象即构造器的name属性。

允许函数存在于块级作用域内
这里先说严格模式

 "use strict";
 var flag = true;
 if (flag) {
      function todo () {}
 }

以上代码在ES5以及之前会报错,而ES6中不会报错,但是函数声明会提升到当前作用域的顶部。

非严格模式中

 "use strict";
 var flag = true;
 if (flag) {
      function todo () {}
 }
 console.log(typeof todo) //function

这里会把函数提升到全局作用域,可以用了let声明方式解决这个问题。

箭头函数

箭头函数语法
箭头函数的表达方式 : var name = value => value;
以上等同于 var name = function (value) { return value } 省略了圆括号、花括号和return语句
需要注意使用箭头函数的时候 如果没有参数时圆括号不能省略

使用箭头函数需要注意的点
1、箭头函数不能作为构造器使用,即不能用new操作符调用
2、this的值取决于最靠近的上层非箭头函数,不能被修改
3、没有arguments对象,不能使用剩余参数访问函数,需要设置参数名
4、没有原型,就是没有prototype属性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值