====================es6對象 新增的對象字面量語法==========================
1. 成員速寫:
如果對象字面量初始化時,成員的名稱來自於一個變量, 並且和變量的名稱相同,則可以進行簡寫
es6以前使用返回對象,需要以下的寫法:
/**
* @description: 創建要給用戶, 返回一個對象
* @param : loginId 登錄的id
* @param : loginPwd 登錄的密碼
* @param : nickName 暱稱
* @return: {*} 返回一個對象
*/
function createUser(loginId, loginPwd, nickName) {
return {
loginId: loginId,
loginPwd: loginPwd,
nickName: nickName,
id: Math.random()
}
}
es6後,可以這麼寫:
/**
* @description: 創建要給用戶, 返回一個對象
* @param : loginId 登錄的id
* @param : loginPwd 登錄的密碼
* @param : nickName 暱稱
* @return: {*} 返回一個對象
*/
function createUser(loginId, loginPwd, nickName) {
return {
loginId,
loginPwd,
nickName,
id: Math.random()
}
}
2. 方法名速寫:
在對象字面量初始化時, 方法可以省略冒號和function:
es6以前:
const user = {
name:'twinkle',
age: 100,
sayHello: function(){
}
}
es6以後:
const user = {
name:'twinkle',
age: 100,
sayHello(){
}
}
3. 計算屬性名
有的時候,初始化對象時, 某些屬性名可能來自於某個表達式,在計算中可以使用中括號來表示該屬性名是通過計算得到的。
例如:
const prop1 = "name";
const porp2 = "age";
// es6 以前創建一個帶有變量的對象屬性需要以下做法
const user = {};
user[prop1] = "twinkle";
user[porp2] = 100;
// es6後可以這麼寫,初始化就可以賦值:
const user1 = {
[prop1]: "twinkle",
[porp2]: 100
}
====================es6對象 新增的對象API==========================
以下方法都是靜態方法,直接應用在Object上:
1. Object.is(obj1, obj2) 用來判斷兩個對象是否相等
用於解決一些歷史遺留問題: 如: NaN === NaN // false \
+0 === -0 // false
用於判斷兩個數據是否相等,基本上是嚴格相等(===)是一致的,除了以下兩點:
1. NaN 與 NaN
2. +0 與 -0
2. Object.assign() 用於對象的混合
如: const obj1 ={a: 123, b: 234}
const obj2 = {c, 123, a:234}
這個方法與es7 的...是一樣的 如{...obj1, ...obj2} 與 Object.assign(obj1, obj2) 相同
Object.assign(obj1, obj2) 這個方法會改動第一個參數,返回的是obj1,巧妙的寫法 Object.assign({}, obj1, obj2)
3. Object.getOwnPropertyNames 的枚舉順序
Object.getOwnPropertyNames() 這個方法之前就存在, 只是沒有明確的要求,如何排序由瀏覽器廠商來排序。
es6規定了該方法的數組的排序如下:
先排數字(升序),在排其他
4. Object.setPrototypeOf() 用於設置某個對象的隱士原型
比如: Object.setPrototypeOf(obj1, obj2) 相當於 obj1.__proto = obj2
===================es6面向對象================
面向對象: 是一種編程思想, 和具體的語言無關
對比面向過程:
面向過程: 思考的切入點是功能的步驟
面向對象: 思考的切入點是對象的劃分
如: [大象裝冰箱]
面向過程的思考如下:
1. 冰箱門打開
2. 大象裝進去
3. 冰箱關上
面向對象的思考如下:
大象對象
冰箱對象
冰箱的方法: 打開
關閉
裝東西
步驟: 1. new 一個冰箱 調用打開的方法
2. new 一個大象 冰箱裝好大象
3. 冰箱的關閉
總結: 面向對象用於大型的項目,更好的維護;面向過程用於小型的項目,快速開發
類: 構造函數的語法糖 class
傳統的構造函數的問題
function Animal(type, name, age, sex) {
this.type = type;
this.name = name;
this.age = age;
this.sex = sex;
}
Animal.prototype.print = function () {
console.log("種類", this.type);
console.log("名字", this.name);
console.log("年齡", this.age);
console.log("性別", this.sex);
}
// 面向對象中, 上面的屬性和方法的定義,統稱爲一個類
const a = new Animal("狗", "旺財", 3, "男")
a.print();
1. 屬性和原型方法定義分離, 降低了可讀性
2. 原型成員可以被枚舉, 方法可以被變量
3. 默認情況下,構造函數仍然可以當作普通函數使用
類的特點:
class Animal {
constructor(type, name, age, sex) {
this.type = type;
this.name = name;
this.age = age;
this.sex = sex;
}
/**
* @description: 打印方法
* @param :
* @return:
*/
print() {
console.log("種類", this.type);
console.log("名字", this.name);
console.log("年齡", this.age);
console.log("性別", this.sex);
}
}
const a = new Animal("狗", "旺財", 3, "男")
a.print();
1. 類聲明不會被提升, 與let 和const 一樣,存在暫時性死區
2. 類中的所有代碼均在嚴格模式下執行
3. 類的所有方法都是不可枚舉
4. 類的所有方法內部都無法當作構造函數使用
5. 類的構造器必須使用 new 來調用
類的其他書寫方式:
1. 可計算的成員名:
如: cosnt printName = "print";
const obj = {
print(){
console.log('打印');
}
}
調用方式:
obj.[printName]() 就是等於obj.print()
2. getter 和 setter 方法
es5 中可以使用 Object.defineProperty() 可以定義某個對象成員屬性的讀取和設置
es5以前使用函數來給一個對象來賦值或者取值
使用getter和setter控制的屬性不在原型上
使用方法: 直接在函數前面加上get set 構造器裏面還是原來的寫法
3.靜態成員: 構造函數本身的成員, 通過new 出來的成員叫做實例原型;
例如: 上面的Animal.abc = "abc" 這個叫做靜態成員
而new 出來的東西叫做實例成員
使用static 定義的成員,就是靜態成員
4. 字段初始化器(es7): 寫成員的時候可以直接賦值
如: class Test{
static a = 1;
b = 2;
c = 3
}
相當於: class Test{
constructor(){
this.a = 1;
this.b = 2;
this.c = 3;
}
}
注意: 1. 使用static的字段初始化器,添加的是靜態成員
2. 沒有使用static的字段初始化器, 添加的成員位於對象上
3. 箭頭函數使用初始化器,存在對象上面,不在原型上
可以通過console.dir(類名)
5. 表達式:
如:
const A = class{ //匿名類,表達式
}
6. 裝飾器(es7): 提示方法以及過時,因爲有的方法更新過程,會在其他地方使用,所以提示後面開發者
使用裝飾器標記方法過期了
語法: @+ 名稱
如: class Test {
@Obsolete
print(){
}
}
// 現在用不了,需要使用babel或者用typescript
function Obsolete(target, methodName, descriptor){
// target function Test
// print
// {value: function print(){},……}
const oldFunc = descriptor.value;
descriptor.value = function(...args){
console.warn(`${methodName}` 方法已經過時了)
oldFunc.apply(this, args)
}
}
es6類的繼承: 如果兩個類A和B,如果可以描述爲:B是A, 則A和B形成繼承關係
如果B是A,則:
1. B繼承自A
2. A派生B
3. B是A的子類
4. A是B的父類
如果A是B的父類,則B會自動擁有A的所有實例成員
es6以前通過, call() 來實現繼承
如:
// 以下代碼實現了了一個動物的方法,要實現狗繼承於動物
function Animal(type, name, age, sex){
this.type = type;
this.name = name;
this.age = age;
this.sex = sex;
}
Animal.prototype.print = function(){
console.log(this);
}
function Dog(name, age, sex){
// 這麼寫可以實現屬性的繼承,但是Dog裏面沒有動物類上的打印方法;
// 原因: 動物的原型上纔有打印的方法, 但是狗的只是使用了動物的構造函數。
// 但是動物的原型並沒有繼承過來, 所以要使狗的隱式原型要使用動物的原型
Animal.call(this, "犬類", name, age, sex);
}
// 這樣就形成了繼承關係了
Object.setPrototypeOf(Dog.prototype, Animal.prototype);
es6的做法如下:
extends: 繼承
super: 1. 直接當作函數來調用,表示父類構造函數
2. 如果當作對象使用,表示調用父類的方法super.print()
例如:
class Animal {
constructor(type, name, age, sex) {
this.type = type;
this.name = name;
this.age = age;
this.sex = sex;
}
print() {
console.log(this)
}
}
class Dog extends Animal{
constructor(name, sex, age){
super("犬類", name, age, sex);
}
}
注意:
es6要求,如果定義了constructor,並且該類式子類,則必須在constructor的第一行手動調用父類的構造函數
如果子類不寫constructor,則會有默認的構造器,該構造器需要的參數和父類一模一樣,並且調用父類的構造器
用js製作抽象類:
該類不能被實例話,只能被繼承
this 執行具體的類
es6 對象學習 總結
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.