后续持续更新
function log(x, y = 'World') { //y默认等于world
console.log(x, y);
let x = 1; // error,参数变量是默认声明的,不能用let或const再次声明。
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
function add(...values) { //values为参数数组。
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
//函数名=(参数)=>代码
var f = () => 5;
// 等同于
var f = function () { return 5 };
var f = v => v;
// 等同于
var f = function (v) {return v;};
//代码块部分多于一条语句,就要使用大括号将它们括起来
var sum = (num1, num2) => {
return num1 + num2;
}
注意:
1.如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
2.(重要哟)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
3.不可以当作构造函数,也就是说,不可以使用new命令。
4.不可以使用arguments对象,可以用 rest 参数代替。
5.箭头函数不能用作 Generator 函数。
扩展运算符
相当于 rest 参数的逆运算,把数组转为用逗号分隔的参数序列。
function add(x, y) {
return x + y;
}
add(...[4, 38]) // 42,把数组转为4 48两个参数
注意:只有函数调用时,扩展运算符才可以放在圆括号中
console.log((...[1, 2])) // Uncaught SyntaxError: Unexpected number
console.log(...[1, 2]) // 1 2
用于对象的合并,该方法的第一个参数是目标对象,后面的参数都是源对象。将源对象的所有可枚举属性,复制到目标对象。
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
注意:
1.如果目标对象与源对象有同名属性,后面的属性会覆盖前面的属性。
2.参数不是对象,则会先转成对象,字符串会以数组形式,拷贝入目标对象。其它基本类型不生效,undefined和null无法转成对象,所以它们不能作为目标对象,即不能放在首参数。
3. 方法属于浅拷贝。对象的任何变化,都会反映到目标对象上面。
const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
对象的扩展运算符用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
通过export命令显式指定输出的代码,再通过import命令输入。
用于输入其他模块提供的功能,文件夹common.js 中
const year = 1958;
const multiply= function(x, y) {
return x * y;
};
export {multiply, year };
可以使用as关键字重命名对象名称
export {
year as year111,
multiply as function111
};
import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(common.js)对外接口的名称相同。
import { multiply, year } from './common.js';
输入的变量都是只读的,不允许在加载模块里改写接口。注意,import命令具有提升效果
// 整体加载的写法:
import * as allconst from './common.js';
console.log(allconst .year);
console.log(allconst .multiply(0,1));
export default function crc32() { // 输出}
import crc32 from '文件名'; // 输入
与export区别:
(1)对应的import语句不需要使用大括号;
(2)一个模块只能有一个默认输出;
本质上,export default就是输出一个叫做default的变量或方法:
export default 42; // 正确
export 42; // 报错
同时输入默认方法和其他接口
export default function (obj) { };
export function each(obj, iterator, context) { };
import _, { each } from 'lodash';
Promise 是异步编程的一种解决方案。包含三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
特点:(1)对象的状态不受外界影响。(2)一旦状态改变,就不会再变。
function Getfetch(url, params,method) { //构造函数
return new Promise( (resolve, reject) => { // 函数作为参数。函数中有两个参数
axios({
method: method,
url:url,
params
}).then(response => {
resolve(response); //resolve将Promise对象的状态从“未完成”变为“成功”
}).catch(error => {
reject(error);//reject将Promise对象的状态从“未完成”变为“失败”
})
} )
};
//then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用,第二个可选。通常不适用第二参数。使用catch捕捉
//catch用于指定发生错误时的回调函数,状态变为rejected时调用。
Getfetch //函数实例
. then(function(response) {}, function(error) {})
. catch(error => console.log(error));
Promise.all(): 该方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例。
const p = Promise.all([p1, p2, p3]);
规则(类似于且逻辑):
(1)只有全部参数的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数,实例使用then。
(2)只要其中之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数,实例使用catch。
注意: 如果作为参数的 Promise 实例,自己定义了catch方法,该实例执行完catch方法后,也会变成resolved。即最后p会调用then方法
const p1 = new Promise((resolve, reject) => {
resolve('hello');
}).then(result => result).catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
}).then(result => result).catch(e => e);
Promise.all([p1, p2]).then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]
特征:(1)function关键字与函数名之间有一个星号。(2)函数体内部使用yield表达式,定义不同的内部状态,yield表达式是暂停执行的标记,而next方法可以恢复执行。
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending'; //没有return语句,返回的value属性值为undefined。
}
//调用 Generator 函数后,该函数并不执行。
var hw = helloWorldGenerator();
//调用遍历器对象的next方法在执行
hw.next() // { value: 'hello', done: false }
hw.next() // { value: 'world', done: false }
hw.next() // { value: 'ending', done: true }
hw.next() // { value: undefined, done: true }
Generator 函数的语法糖。async函数返回一个 Promise 对象,可以使用then方法添加回调函数。
async function getStockPriceByName(name) {
const symbol = await getStockSymbol(name);//遇到await,等到异步操作完成,再接着执行函数体内后面的语句。
const stockPrice = await getStockPrice(symbol);
return stockPrice;//return语句返回的值,会成为then方法回调函数的参数。
}
getStockPriceByName('goog').then(function (result) {
console.log(result);
});
注意:
1.async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。//throw new Error(‘出错了’);
2.必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。
class 类的本质还是一个函数,类本身就指向构造函数。
class Point { //内部默认使用严格模式
constructor(x, y) { // 当new一个实例,默认有一个constructor,不管写没写
this.x = x; //this关键字则代表实例对象
this.y = y;
}
//不需要逗号分隔
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
//类的内部所有定义的方法,都是不可枚举的
doStuff() {
console.log('输出');
}
};
// 等同于
Point.prototype = {
constructor() {},
toString() {},
doStuff() {},
};
//给class类添加方法
Object.assign(Point.prototype, {
toString(){},
toValue(){}
});
var b = new Point (2, 3); //类必须使用new调用
b.constructor === Point .prototype.constructor // true
b.doStuff() // "输出"
1.类必须使用new调用,否则报错。
2.类不存在变量提升。 即new必须在关键字class之后
3.与 ES5 一样,类的所有实例共享一个原型对象。
var p1 = new Point(2,3);
var p2 = new Point(3,2);
p1.__proto__ === p2.__proto__ //true
4.class类的静态方法
如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Foo {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.color= color;
}
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod() //报错
5.继承
使用extends可以实现继承。子类必须在constructor方法中调用super方法,子类没写默认添加。在子类的构造函数中,只有调用super之后,才可以使用this关键字,
class Bar extends Foo {
constructor(x, y, color) {
this.color = color; // ReferenceError
super(x, y,color); // 调用父类的constructor
this.color = color; // 正确
}
toString() {
return this.color + ' ' + super.classMethod(); // 调用父类的toString()
}
}
let cp = new Bar (25, 8, 'green');
Bar.classMethod(); //classMethod是静态属性
cp.toString(); //green hello