一、let和const命令
let使用时需要注意的点首先let 可以设置块级作用域,相对于es5 没有块级作用域,要使用立即执行函数来实现块级作用域,let更加简单。而且这种写法有利于代码的规范,必须先定义再赋值,不然会出错.
es5写法
function test(){
var arr = [];
for (var i = 0; i < 5; i++) {
arr[i] = function(){
return i;
}
console.log(arr[i]());
}
console.log(i); //5
console.log(arr[1]()); //5
}
test(); //0,1,2,3,4
es6写法
function test(){
var arr = [];
for (let i = 0; i < 5; i++) {
arr[i] = function(){
return i;
}
console.log(arr[i]());
}
console.log(i); //出错,访问不到局部作用域,i is not defined
console.log(arr[1]()); //1
}
test(); //0,4
let 和var 之间的区别,以及暂时性死区的说法,就是在块级作用域声明let ,在整个块里,到let 声明变量这一行为止,前面使用let声明的同名变量都会出错,而且在同一个块级作用域内,let 和const 不能声明同名的变量。
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
function a() {
let a = 10; //此时不管是var ,const, let都不行
let a = 1;
}
a();
const使用时需要注意的点.const 声明一个只读的常量。一旦声明,常量的值就不能改变,而且要在声明的时候就赋值,不然以后赋值就会出现错误,这样的做法是为了让其他人无法随意改变这个值
const PI = 3.1415;
PI = 3; // 常规模式时,重新赋值无效,但不报错
console.log(PI) // 3.1415
对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心
foo = {};
foo.prop = "hello";
foo.age = 12;
foo.prop = "world";
console.log(foo.prop); //world
const foo = {};
foo.prop = "hello";
foo.age = 12;
foo.prop = "world";
console.log(foo.prop);
foo = {}; //这里会报错,const定义的类型不能重新复制,属性和之前一样可以重新赋值</code></pre>
可以冻结对象,使用 Object.freeze({});
const foo = Object.freeze({});
foo.prop = 123;
foo.age = 12;
console.log(foo); //object {}
console.log(foo.age); //undefined
全局属性,es5 中 let function 声明的都是全局变量和全局对象的属性是等价的,而let const class 声明的全局变量和全局对象的属性是不相等的
var a = 1;
window.a // 1
console.log(window.a);
let b = 1;
window.b // undefined
变量的解构赋值、对象的解构赋值
1. 之前的写法(原理就是匹配)
var a =1; var b=2; var c= 3;
var [a,b,c] = [1,3];
2. 解构赋值允许使用默认值
var [foo=-true] = [];
对象的解构赋值
1. var { foo,bar } = { foo: "aaa",bar: "bbb" };
// 实际上 var { foo :foo,bar: bar } = { foo: "aaa",bar: "bbb" };
字符串的解构赋值
const [a,c,d,e] = 'hello'; // a = 'h';
数值和布尔值的解构赋值
let {toString: s} = 123;
let {toString: s} = true;
函数参数的解构赋值
function add([x,y]){
return x + y;
}
add([1,2]); // 3</code></pre>
二、字符串的扩展
1.字符的Unicode表示法
u0000——uFFFF
"u0061" // 'a'
超出以上范围的要使用两个字节以上表示
uD842uDFB7
2. JavaScript内部,字符以UTF-16的格式储存,每个字符固定为2个字节
3.
var str = "abc"; console.log(str.charAt(0)); console.log(str.charCodeAt(0));console.log(str.charAt(2));
// a 97 c
4. ES6 增加检测字符串新方法
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。
5. repeat()
repeat方法返回一个新字符串,表示将原字符串重复n次。
'a'.repeat(3); //
6. 模板字符串
$('#result').append(
'There are ' + basket.count + ' ' +
'items in your basket,' +
'' + basket.onSale +
' are on sale!'
);
$('#result').append( There are <b>${basket.count}</b> items in your basket,<em>${basket.onSale}</em> are on sale! );
字符串里面的变量 使用 ${val}
三、正则扩展
原来的方法 match()、replace()、search()和split()。
1. 新添加 u扩展 ,表示可以匹配大于 uffff的字符
2. 新添加flags
// ES5的source属性
// 返回正则表达式的正文
/abc/ig.source
// "abc"
// ES6的flags属性
// 返回正则表达式的修饰符
/abc/ig.flags
// 'gi'
四、数值的扩展
1. 二进制和八进制表示法 (0b)二进制 (0o)八进制
2. Number.isFinite(),Number.isNaN() //非数值一律返回false
3. Number.parseInt('12.34') // 12 Number.parseFloat('123.45#') // 123.45
ES6 写法有变 ,之前定义在全局 ,现在全部放到了number上
4. Math 对象上方法的扩展
MAth.trunc() //返回整数部分
Math.sign() //判断一个数是正数、负数、还是0
Math.cbrt() //计算立方根
Math.hypot() //方法返回所有参数的平方和的平方根。
Math.expm1(x) //返回ex - 1,即Math.exp(x) - 1。
Math.log1p(x) //方法返回1 + x的自然对数,即Math.log(1 + x)。
Math.log10() //方法返回以10为底的x的对数
Math.log2(x)返回以2为底的x的对数。
ES7新增了一个指数运算符(),目前Babel转码器已经支持。
2 2 // 4
2 ** 3 // 8
五、数组的扩展
1. Array.from
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a','b','c']
//[].slice.call(obj) //其中obj 为类数组对象
slice()方法可以
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a','c']
2. Array.of
Array.of方法用于将一组值,转换为数组。
Array.of(1,3) // [1,3]
3. 数组实例的find()和findIndex()
4. 数组实例的fill方法使用给定值,填充一个数组。
['a','c'].fill(7)
// [7,7,7]
5.ES6提供三个新的方法——entries(),keys()和values()——用于遍历数组,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
6.数组实例的includes() //判断数组是否包含某个值,ES7
六、函数的扩展
1. 函数参数的默认值
2. rest参数
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2,5,3) // 10
3. 扩展运算符 ...
console.log(1,...[2,4],5)
// 1 2 3 4 5
4. 箭头函数
var f = v => v;
上面的箭头函数等同于:
var f = function(v) {
return v;
};
// Expression bodies
var odds = evens.map(v => v + 1); //只有一个参数,没有参数需要使用一对空括号括起来
var nums = evens.map((v,i) => v + i); //两个参数要使用括号
var pairs = evens.map(v => ({even: v,odd: v + 1})); //返回值为对象需要在外面再加一对圆括号
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
}); //执行函数体时加大括号
在ES6 返回JSX时
return (
<a href="#"
onClick={e => {
e.preventDefault()
onClick()
}}
{children}
)
七、对象的扩展
1. 属性的简洁表示法、方法的简写
var foo = 'bar';
var baz = {foo}; ===== var baz = {foo: foo}
baz // {foo: "bar"}
//方法的简写
var o = {
method() {
return "Hello!";
}
};
var o = {
method: function() {
return "Hello!";
}
};
-
属性名表达式
var lastWord = 'last word';
var a = {
'first word': 'hello',[lastWord]: 'world'
};
这在ES5是不允许的
-
Object.is()
Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致,与ES5相比较而言,
增加 NAN == NAN 、-0 != +0 ,需要注意的一点 {} != {} ,这是两个不同的引用
-
Object.assign()
方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。方法实行的是浅拷贝,而不是深拷贝
-
Object.values(),Object.entries()
ES5引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
Object.values 返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
Object.values 返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对。
var obj = { foo: 'bar',baz: 42 };
Object.entries(obj)
// [ ["foo","bar"],["baz",42] ]
八、Symbol
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。目的是防止属性名冲突。
1. 不能使用 new 声明如 var s1 = Symbol();
2. Symbol值不能与其他类型的值进行运算 如字符连接
3. Symbol值可以显式转为字符串、bool值
4. 魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。
九、set 和 map 结构
Set
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成Set数据结构。
1. Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。
2. Set添加成员方法 var n = new Set();
add(value):添加某个值,返回Set结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。
3. Set 遍历方法
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
WeakSet
WeakSet的成员只能是对象,而不能是其他类型的值。WeakSet是不可遍历的
1. WeakSet是一个构造函数,可以使用new命令,创建WeakSet数据结构。
2. 作为构造函数,WeakSet可以接受一个数组或类似数组的对象作为参数。
Map
ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object更合适。Map的遍历顺序就是插入顺序。
Map结构的实例有以下属性和操作方法。
size() 返回map结构成员数量
set(key,value):设置对应键值,返回map结构。
get(key): 通过键名获取键值
delete(key):删除某个值,返回一个布尔值,表示删除是否成功。
has(key):返回一个布尔值,表示该值是否为map的成员。
clear():清除所有成员,没有返回值。
keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回所有成员的遍历器。
forEach():遍历Map的所有成员。</code></pre>
WeakMap
WeakMap结构与Map结构基本类似,唯一的区别是它只接受对象作为键名(null除外),不接受其他类型的值作为键名,
九、Promise对象
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。一旦状态改变,就不会再变.
创建promise 对象方法
var promise = new Promise(function(resolve,reject) {
// ... some code
if (/ 异步操作成功 /){
resolve(value);
} else {
reject(error);
}
});
Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
promise.then(function(value) {
// success
},function(error) {
// failure
});
十、Class
//ES5写法
function Point(x,y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ',' + this.y + ')';
};
var p = new Point(1,2);
//ES6 class 写法
class Point {
constructor(x,y){
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ',' + this.y + ')';
}
}
- 实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)。
- Class不存在变量提升(hoist),这一点与ES5完全不同。
- 与函数一样,类也可以使用表达式的形式定义。
const MyClass = class Me {
getClassName() {
return Me.name;
}
};
上面代码使用表达式定义了一个类。需要注意的是,这个类的名字是MyClass而不是Me,Me只在Class的内部代码可用,指代当前类。
Class 的继承
class ColorPoint extends Point {}
十一、Module
import
从fs模块加载3个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载
// ES6模块
import { stat,exists,readFile } from 'fs';
//整体加载的写法如下。
import * as circle from './circle';
console.log('圆面积:' + circle.area(4));
console.log('圆周长:' + circle.circumference(14));
export
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。
export default 命令
// 写法
export var m = 1;
export default function foo() {
console.log('foo');
}
// 或者写成
function foo() {
console.log('foo');
}
export default foo;
import customName from './export-default'; //导出名字自定义 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|