说明
目前标准是ES6,主要参考来自于阮一峰的《ECMAScript 6入门》。
细节知识还是查阅API文档进行学习,官网地址:https://developer.mozilla.org/en-US/docs/Web
测试环境
直接使用 node 作为js的测试环境, node 版本为:8.1.3。
关于如何安装nodejs,自己去查看网上教程。
说明:要是发现一些新特性没有支持,首先查看当前版本node是否支持新特性,如果支持有可能是默认没有开启。
数据类型
JS中拥有如下几种数据类型:
- 字符串
- 数字
- 布尔值
- 数组
- 对象
- Null
- Undefined
JS的变量都是动态类型的,可以随时改变变量的数据类型。
函数的拓展
参数默认值
可以允许参数有默认值,在调用时可以不用传入该参数,但是要注意默认参数的位置。(后面讲)
function fun(x, y = “hello”) {
console.log(x, y);
}
let x = 1;
let y = 2;
fun(x); // 1 “hello”
fun(x, y); // 1 2
解构赋值
参数默认值可以与解构赋值一起使用。
function test({ payload: { x, y = 4 } }) {
console.log(x, y);
}
var payload = { x: 1, y: 2 };
test({ payload });
默认参数的位置
定义了默认值的参数,通常放在函数的尾部。至于为什么,可以自己去想想,也很简单。
function test(x, y = 1) {
console.log(x, y);
}
对象的拓展
析构赋值
// 对象
const user = { name: 'guanguan', age: 2 };
const { name, age } = user;
console.log(`${name} : ${age}`); // guanguan : 2
// 数组
const arr = [1, 2];
const [foo, bar] = arr;
console.log(foo); // 1
可以将析构传入函数参数
const add = (state, { payload }) => {
return state.concat(payload);
};
析构还可以配上alias,让代码更加具有意义。
const add = (state, { payload: todo }) => {
return state.concat(todo);
};
技巧:
函数参数需要对象中的一个参数或多个参数时,只获取到了有用的成员变量的值。
var Person = { name: “pingsoli”, age: 20, sex: 1 };
functio outputInfo({ name, age }) {
console.log(name + “:” + age);
}
outputInfo(Person);
// pingsoli:20
属性赋值
这个是一个析构的反向操作,用于重新组织一个object。
const name = ‘pingsoli’;
const age = 8;
const user = { name, age }; // { name: ‘pingsoli’, age: 8 }
对象属性
对象属性有三个特点:
可迭代:通过for..in循环访问对象所有属性。
可修改:访问属性,增加属性,修改属性,删除属性。
可配置:修改属性行为,可以让其不可迭代,不可修改和不可配置。
var ob = { a: 1 };
ob.a; // 访问ob
ob.a = 0; // 修改属性a的值
ob.a = ‘hello world’ // 修改属性值,并将属性a变为一个string类型
ob.b = 2; // 新增属性
delete ob.b; // 删除属性
// 可迭代
for (let key in ob) {
console.log(ob[key]);
}
// 可配置
Object.defineProperty(ob, 'c', {
value: 3,
enumerable: false,
writable: false,
configurable: false
});
上面使用了Object.defineProperty来配置属性 ‘c’, 使其不可迭代,不可修改,不可配置。
Spread操作符
用于组装数组。
const todos = [‘learn dva’];
[...todos, ‘learn antd’]; // [‘learn dva’, ‘learn antd’]
用户获取数组的部分项。
const arr = [‘a’, ‘b’, ‘c’];
const [first, ...rest] = arr;
rest; // [‘b’, ‘c’]
const [first, ,...rest] = arr;
rest; // [‘c’]
收集函数参数为数组。
function direction(first, ...rest) {
console.log(rest);
}
direction(‘a’, ‘b’, ‘c’); // [‘b’, ‘c’]
容器
set
类似于数组,但是值唯一。
语法: new Set([iterable])
常用方法:
set.add(value)
set.delete(value)
set.has(value)
set可以很简单的实现并集(Union)、交集(Intersect)和差集(Difference)。
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// {2, 3}
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// { 1 }
map
存储键值对。
语法:new Map([iterable])
基本用法:
const map = new Map([
[‘name’, ‘pingsoli’],
[‘title’, ‘author’]
]);
map.size
map.has(‘name’);
map.get(‘name’);
map.get(‘title’);
Promise
语法知识:
new Promise( /* executor */ function(resolve, reject) { ... } );
Promise用于更加优雅的处理异步请求。
Promise有三种状态:
未完成状态(pending):初始化状态,即没有完成没有拒绝。
已完成状态(fulfilled):操作成功
失败状态(rejected):操作失败
两种转换形态:
未完成状态 -> 已完成状态
未完成状态 -> 失败状态
Promise基本方法:
Promise.reject(reason)
Promise.resolve(value)
Promise.prototype.catch(onRejected)
Promise.prototype.then(onFulfilled, onRejected)
const delay = (timeout) => {
return new Promise(resolve => {
setTimeout(resolve, timeout);
});
};
// 没有参数可以用下划线或者()
delay(1000).then(_ => {
console.log(‘executed’);
});
应用场景
加载图片
const preloadImage = function(path) {
return new Promise(function (resolve, reject) {
var image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
}
generator
函数名前面有一个星号 ‘*’
函数体内部使用yield表达式
运行generator函数会返回一个Iterator实例,调用Iterator的next方法可以将yield后面的值包装成固定对象并返回,如果运行到函数结尾,那么就会返回underfined。
function *gen() {
yield 1;
yield 2;
}
var g = gen();
console.log(g.next());
console.log(g.next());
console.log(g.next());
// output :
{ value: 1, done: false }
{ value: 2, done: false }
{ value: undefined, done: true }
说明:不能再非generator函数中使用yield。
yield 表达式
将yield关键字后面的内容进行包装,然后返回。
yield* 表达式
可以让generator中再套上一个generator。
yield* 函数()
function* foo() {
yield 1;
yield 2;
}
function* bar() {
yield 'x';
yield* foo();
yield 'y';
}
for (let v of bar()) {
console.log(v);
}
// output:
x
1
2
y
API
JSON.stringify()
将对象变为JSON的字符串形式。
let a = { b: ‘hello’, c: 2 };
console.log(JSON.stringify(a));
// “{“b”: “hello”, “c”: 2 }”
FileReader
FileReader是一个web API对象,能够让网络应用程序异步读取本地文件内容。
使用例子
<input type=“file” id=“upload_file” />
<div id=“file_content”></div>
...
function load() {
let reader = new FileReader();
let file = document.getElementById('upload_file').files[0];
reader.addEventListener('load', () => {
document.getElementById('file_content').innerHTML=reader.result;
})
reader.readAsText(file);
}
FAQ
Q: JS中的 == 和 === 的区别?
A: == 是不进行类型比较,直接将两边的操作数变为统一类型,然后进行比较。
而 === 首先进行类型比较,如果不一致,就是不相等。
Q: Nodejs使用ES6新特性时出错?
A: node --harmony app.js
ES6中一些新特性没有被nodejs支持,目前为止不能开启node支持ES6特性模式。
但是可以使用--harmony
,来支持ES6新语法特性。
如果是linux平台,那么使用alias将会使非常好的效果,不用每次带一个 -- harmony
参数。
(Ubuntu)在/etc/bash.bashrc中添加:
alias node=’node --harmony’
Q: 查看对象类型?
A: typeof xxx
或者 typeof(xxx)
。
Q: 单引号和双引号有什么区别?
A: 在JavaScript中没有区别。
Q: 替换字符串中特定的字符?
A: 使用string.replace方法。
例子:去掉日期中间的横线, 2017-01-01.
let date = “2017-01-01”;
date = date.replace(“-”, “”);
上面只能替换一处,结果为: 201701-01
使用全局替换:
date = date.replace(/-/g, “”);
结果为:20170101
Q: 创建对象数组?
A:
let csvData = []; // 声明csvData是一个数组
for (let i = 0; i < size; i++) {
csvData[i] = new Object(); // 为每个数组元素创建一个对象
csvData[i].name = “pingsoli”;
csvData[i].aga = 90;
csvData[i].sex = “male”;
}
参考
[1] 阮一峰: ECMAScript 6 入门
[2] JavaScript属性:可迭代、可修改和可配置。
http://blog.csdn.net/u010278882/article/details/50630704
[3] Promise:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[4] JavaScript API查看:
https://developer.mozilla.org/en-US/docs/Web