一、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);
}