一、export 和import
模块功能主要由两个命令构成:export
和import
。export
命令用于规定模块的对外接口,import
命令用于输入其他模块提供的功能。
你希望外部可以读取模块内部的某个变量,就要用export
,下面的例子是用export
命令输出变量。
// information.js
export var name = 'jack';
export var age = 18;
export var sex = '男';
上面这个例子ES6将其视为一个模块,里面使用export
对外输出了三个变量
对于上面的例子export
还有另外一种写法
// information.js
var name = 'jack';
var age = 18;
var sex = '男';
export {name, age, sex};
export
一旦暴露出有名字的就需要用大括号进行接收
// utils.js
export let sum = (x, y) => {
return x + y;
}
export let minus = (x, y) => {
return x - y;
}
// mian.js引入
// 方法1
import {sum, minus} from './utils';
// 方法2
import * as util from './utils';
async 和 await
async/await
是写异步代码的新方式,优于回调函数和Promise
。async/await
是基于Promise
实现的,它不能用于普通的回调函数。async/await
与Promise
一样,是非阻塞的。async/await
使得异步代码看起来像同步代码,再也没有回调函数。但是改变不了JS单线程、异步的本质。
用法
- 使用
await
,函数必须用async
标识 await
后面跟的是一个Promise
实例- 需要安装
babel-polyfill
,安装后记得引入npm i --save-dev babel-polyfill
- 接口的封装
import axios from 'axios';
function getNews() {
return new Promise((resolve, reject) => {
axios.get('api/api/comment/list/?group_id=6569417656087085581&item_id=6569417656087085581&offset=0&count=5').then(res => {
resolve(res);
}).catch(err => {
reject(err);
});
})
}
export default {getNews};
- 组件里面封装
methods: {
async getUsers() {
this.user = await this.$api.getNews();
}
},
mounted() {
this.getUsers();
}
数组条件过滤
单条件筛选,数组的filter
方法就能够满足需求
单条件单数据筛选
要刷选的数组
let persons = [
{name:'zhangsan', age: 23, sex:'男'},
{name:'lisi', age: 16, sex:'男'},
{name:'Jay', age: 19, sex:'男'},
{name:'Mark', age: 40, sex:'女'}
]
查找lisi
这条数据
- 使用
filter
方法
// filter刷选 (查询李四)
let person = persons.filter(item => item.name === 'lisi')
// 打印结果 [{name: "lisi", age: 16, sex: "男"}]
- 使用
find
来查询
let findPerson = persons.find(item => item.name === 'lisi')
// 打印结果 {name: "lisi", age: 16, sex: "男"}
filter查询到是一个数组,find查询到的数组里面单位一个对象
Array.prototype.some
使用 some()
方法会比使用 find()
方法更加高效简洁。some()
方法是返回布尔值而 find()
方法是返回符合条件的第一个元素值
// 查找是否有lisi
let result = persons.some(item => item.name === 'lisi')
// result ---> true
对象扩展
扩展运算符
let obj = [{name: 'xxx', age: 1}]
obj = obj.map(item => {
return {...item, sex: '女'}
})
// 输出
[{name: 'xxx', age: 1, sex: '女'}]
1.属性的简洁表示法
ES6 允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
// es6简写
let foo = '123';
let baz = {foo};
console.log(baz); // {foo: "123"}
// 等价于
let baz = {foo: '123'};
console.log(baz); // {foo: "123"}
ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。
方法也可以简写
const methods = {
eating: function(someting) {
console.log(`正在吃${someting}`);
}
}
methods.eating('肉'); // 正在吃肉
// 等价于
const methods = {
eating(someting) {
console.log(`正在吃${someting}`);
}
}
methods.eating('肉'); // 正在吃肉
具体的例子
const birthday = '1994/08/15';
const Person = {
name: 'jack',
birthday,
hello(){
console.log(`我叫${this.name},生日是${this.birthday}`);
}
}
2.属性名表达式
在javascript
定义对象的属性有两种放法
// 方法1
obj.foo = '123';
// 方法2
obj['a'+'b'] = '123';
方法一是直接用标识符作为属性名,方法二是用表达式作为属性名,这时要将表达式放在方括号之内。
注:在ES5中只能使用方法一(标识符)定义属性。
var obj = {
foo: true,
abc: 123
};
ES6 则允许字面量定义对象时,用(表达式)作为对象的属性名,即把表达式放在方括号内。
let isGet = 'state';
let obj = {
[isGet]: true,
['a'+'b']: '123'
};
console.log(obj); // {state: true, ab: "123"}
3.方法的name属性
函数的name
属性可以返回函数的名字。对象方法也是函数,因此也有name
属性。
const Person = {
sayHello() {
console.log('hello!');
}
};
console.log(Person.sayHello.name); // sayHello
可以看到name属性返回的就是方法名字
对象的方法如果使用了取值函数(getter
)和存值函数(setter
),则name
属性不是在该方法上面,而是该方法的属性的描述对象的get
和set
属性上面,返回值是方法名前加上get
和set
。
const obj = {
get personname() {},
set personname(x) {}
}
console.log(obj.personname.name); // Cannot read property 'name' of undefined
// 获取指定对象的自身属性描述符。自身属性描述符是指直接在对象上定义(而非从对象的原型继承)的描述符。
const descriptor = Object.getOwnPropertyDescriptor(obj, 'personname');
console.log(descriptor.get.name);
console.log(descriptor.set.name);
4.Object.is()
ES6 提出“Same-value equality
”(同值相等)算法,用来解决相等运算符 ( == )
和严格相等运算符 ( === )
的缺点,它用来比较两个值是否严格相等,与严格比较运算符的行为基本一致。
console.log(Object.is('a', 'a')); // true
console.log(Object.is({}, {})); // false
**( === )**和Object.is()的区别
console.log(+0 === -0); // true
console.log(NaN === NaN); // false
console.log(Object.is(+0, -0)); // false
console.log(Object.is(NaN, NaN)); // true
5.Object.assign()
Object.assign
方法用于对象的合并,将源对象(source)
的所有可枚举属性,复制到目标对象(target)
。
const target = {a: 1};
const source1 = {b: 2};
const source2 = {c: 3};
Object.assign(target, source1, source2);
console.log(target); // {a: 1, b: 2, c: 3}
Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
const target = {a: 1, b: 1};
const source1 = {b: 2, c: 2};
const source2 = {c: 3};
Object.assign(target, source1, source2);
console.log(target); // {a: 1, b: 2, c: 3}
只有一个参数,则会返回这个参数
const obj = {a: 1};
console.log(obj); // {a: 1}
(1)浅拷贝
Object.assign
方法实现的是浅拷贝,而不是深拷贝。如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
console.log(obj2.a.b);
上面的代码,源对象obj1属性a的值是一个对象,Object.assign
拷贝得到的是这个对象的引用。这个对象任何变化都会反映到目标对象上面。
(2)同名属性的替换
对于嵌套对象,一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。
const target = {a: {b: 'c', d: 'e'}};
const source = {a: {b: 'hello'}};
console.log(Object.assign(target, source)); // { a: { b: 'hello' } }
可以看出target对象的a属性被source对象的a属性整个替换掉了
(3)数组的处理
Object.assign
可以用来处理数组,但是会把数组视为对象。
console.log(Object.assign([1, 2, 3], [4, 5])); // [4, 5, 3]
Object.assign
把数组视为属性名为 0、1、2 的对象,因此源数组的 0 号属性4覆盖了目标数组的 0 号属性1。
(4)取值函数的处理
Object.assign
只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。
const source = {
get foo() { return 1 }
};
const target = {};
Object.assign(target, source);
console.log(target.foo);
source
对象的foo
属性是一个取值函数,Object.assign
不会复制这个取值函数,只会拿到值以后,将这个值复制过去。
常见用途
(1)为对象添加属性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
let point = new Point(1, 2);
console.log(point); // Point {x: 1, y: 2}
通过Object.assign
方法,将x属性和y属性添加到Point
类的对象实例。
(2)为对象添加方法
(3)克隆对象
function clone(origin) {
return Object.assign({}, origin);
}
采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码。
function clone(origin) {
let originProto = Object.getPrototypeOf(origin);
return Object.assign(Object.create(originProto), origin);
}