JavsScript学习

来源:互联网 发布:编程电缆 质量 编辑:程序博客网 时间:2024/06/06 02:35

说明

目前标准是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;   // 访问obob.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.sizemap.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:x12y

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