一、变量的声明和作用域
块级作用域
(1)let 取代 var
ES6 提出了两个新的声明变量的命令:let和const。其中,let完全可以取代var,因为两者语义相同,而且let没有副作用。‘use strict’;
if (true) {
let x = 'hello';}
for (let i = 0; i < 10; i++) {
console.log(i);
}
上面代码如果用var替代let,实际上就声明了两个全局变量,这显然不是本意。变量应该只在其声明的代码块内有效,var命令做不到这一点。var命令存在变量提升效用,let命令没有这个问题。
'use strict';
if (true) {
console.log(x); // ReferenceError
let x = 'hello';
}
上面代码如果使用var替代let,console.log那一行就不会报错,而是会输出undefined,因为变量声明提升到代码块的头部。这违反了变量先声明后使用的原则。所以,建议不再使用var命令,而是使用let命令取代。
(2)全局常量和线程安全在let和const之间,建议优先使用const,尤其是在全局环境,不应该设置变量,只应设置常量。
const优于let有几个原因。
- 一个是const可以提醒阅读程序的人,这个变量不应该改变;
- 另一个是const比较符合函数式编程思想,运算不改变值,只是新建值,而且这样也有利于将来的分布式运算;
- 最后一个原因是 JavaScript 编译器会对const进行优化,所以多使用const,有利于提高程序的运行效率,也就是说let和const的本质区别,其实是编译器内部的处理不同。
// bad
var a = 1, b = 2, c = 3;
// good
const a = 1;
const b = 2;
const c = 3;
// best
const [a, b, c] = [1, 2, 3];
const声明常量还有两个好处,一是阅读代码的人立刻会意识到不应该修改这个值,二是防止了无意间修改变量值所导致的错误。所有的函数都应该设置为常量。长远来看,JavaScript 可能会有多线程的实现(比如 Intel 公司的 River Trail 那一类的项目),这时let表示的变量,只应出现在单线程运行的代码中,不能是多线程共享的,这样有利于保证线程安全。
二、对象、数组、字符串的解构
1.数组的解构:数组的解构根据位置进行解构
let [a,b,c] = [1,2,3]
// a = 1, b = 2, c = 3
带默认值的
'let [a,b,c='默认值'] = ['Elas','Joseph']
// a = 'Elas', b = 'Joseph', c = '默认值'
2.对象的解构:对象的解构根据key值(变量名)解构
let { name, age } = {"name":"Joseph","age":21}
// name = "Joseph", age = 21
三、对象扩展运算符(…)深拷贝
function joseph(...arg){
console.log(arg[0])
console.log(arg[1])
console.log(arg[2])
console.log(arg[3])
console.log(arg[4])
}
joseph(1,2,3,4,5)
1.reset参数
ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
2扩展运算符
对象的扩展运算符(…)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
由于数组是特殊的对象,所以对象的扩展运算符也可以用于数组。
let foo = { ...['a', 'b', 'c'] };
foo
// {0: "a", 1: "b", 2: "c"}
如果扩展运算符后面是一个空对象,则没有任何效果。
{...{}, a: 1}
// { a: 1 }
如果扩展运算符后面不是对象,则会自动将其转为对象。
// 等同于 {...Object(1)}
{...1} // {}
剩余操作符(rest operator),是解构的一种,意思就是把剩余的东西放到一个array里面赋值给它。一般只针对array的解构
let a = [1,2,3];
let [b, ...c] = a;
b; // 1
c; // [2,3]
// 也可以
let a = [1,2,3];
let [b, ...[c,d,e]] = a;
b; // 1
c; // 2
d; // 3
e; // undefined
// 也可以
function test(a, ...rest){
console.log(a); // 1
console.log(rest); // [2,3]
}
test(1,2,3)
3.箭头函数
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
4.Array.form()
方法从一个类似数组或者可迭代的对象创建一个新的,浅拷贝的数组实例
console.log(Array.from('foo'));
// expected output: Array ["f", "o", "o"]
console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]
5.Object.keys(data)
获取data对象所有属性名组成的数组
四、字符串模板(两个上顿号 )
在其中间通过 ${ xxx} 加入变量名等
五、数组的操作
let json = { '0' : 'Joseph', '1' : 'Elas', '2': 'xxx' , length: 3}
let arr = Array.from(json)
Array.of( ) // 转换成数组
find( ) // 在数组中查找一项,找到了返回该值,找不到返回undifined
fill( ) // 替换数组中的项:接收三个参数,第一个参数是要换成的值,第二个参数是开始换的位置,第三个参数是结束的位置(index+1)
// 数组循环
for( let item of arr){
console.log(item) // 输出值
}
// 输出下标
for( let item of arr.keys){
console.log(item) // 输出值
}
// 输出下标和值
for( let [index,item] of arr.entities){
console.log(index + ' :' item) // 输出下标和值
}
六、函数的扩展和箭头函数
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
七、对象函数的解构josn
let json = {
a: ' Lily ',
b: ' Joseph '
}
function( { a, b = ' web' } ){
console.log( a , b )
}
fun( json )
in 判断数组中的对应下标上是否有值
let arr = [ 'Joseph' , ' ' , ' ' ]
console.log( 0 in arr ) // true
console.log( 1 in arr ) // false
console.log( 2 in arr ) // false
数组的遍历
- forEach()
- filter() // 和forEach差不多
- some()
- map()
八、函数赋值
函数赋值
let name = ' Joseph '
let skill = ' web '
let obj = { name, skill }
// { name: ' Joseph ', skill: ' web '}
key值的构建
let key = ' skill '
let obj = {
[ key ] : ' web '
}
console.log( obj )
// { skill : ' web ' }
Object.assign() 合并对象
let a = ' Joseph '
let b = ' Elas '
let c = ' web '
let obj = Object.assign( { a,b,c } )
console.log(obj)
// {a: "Joseph", b: "Elas", c: "web"}
Symbol – 数据类型
set – 数据结构
最重要的功能是去重
let setArr = new Set([ ' Joseph ', ' web ' , ' vue '])
// 查看元素的长度
console.log( setArr.size )
// 添加元素
setArr.add( ' HTML ' )
// 查找元素
setArr.has( ' xxx ' ) // 存在返回true, 不存在返回false
// 删除单个元素
setArr.delete( ' web ' )
// 删除所有元素
setArr.clear()
// 循环输出的方式
// for ... of
for( let item of setArr ){
console.log(itrm)
}
// forEach
WeakSet // 对象set
Map 数据结构
let map = new Map()
// 设置值
map.set(' xx ',xxx)
// 取值
map.get('xxx')
// 删除
map.delete(' keys ')
// 删除全部
map.clear()
// 查看数量
map.size()
// 查找 --- 返回true/false
map.has()
proxy 代理 在es6中增强对象和函数(方法) 相当于一种声明周期的钩子函数,作为一种预处理
// 正常的语句
let obj = {
add:function( val ){
return val + 100;
},
name: ' I am Joseph'
}
console.log(obj.add( 100 )) // 200
// proxy预处理
// let pro = new Proxy( { 要处理的函数 } , { 预处理 } )
// 预处理函数有三个 get \ set \ apply
let pro = new Proxy( {
add:function( val ){
return val + 100;
},
name: ' I am Joseph'
} , {
get:function( target , key , property ){
// 这其中target就是上面的boj,key是要获取的键
return target[ key ]
}
set:function( target , key , value , receiver ){
return target[key] = value;
}
} )
get属性
get属性是在你得到某对象属性值时预处理的方法,他接受三个参数
- target:得到的目标值
- key:目标的key值,相当于对象的属性
- property:这个不太常用。
set属性
set属性是值你要改变Proxy属性值时,进行的预先处理。它接收四个参数。
- target:目标值。
- key:目标的Key值。
- value:要改变的值。
- receiver:改变前的原始值。
apply的使用
apply的作用是调用内部的方法,它使用在方法体是一个匿名函数时。看下边的代码。
get = function () {
return 'I am JSPang';
};
var handler = {
apply(target, ctx, args) {
console.log('do apply');
return Reflect.apply(...arguments);
}
}
var pro = new Proxy(target, handler);
console.log(pro());