[ES6] 对象

新增对象字面量语法

1. 成员速写

如果对象字面量初始化时,成员的名称来自于一个变量,并且和变量的名称相同,则可以进行简写。

function person(userName, password, nickName) {
    return {
        userName: userName,    // 原本
        password,              // 简写
        nickName
    }
}
2. 方法速写

对象字面初始化时,方法可以省略冒号和function关键字

const obj = {
    name : "abc",
    age : 20,
    //简写前
    sayHello: function() {
        console.log(this.name)
    }
    //简写后
    sayHello(){
        console.log(this.name)
    }
}
3. 计算属性名

有的时候初始化对象,某些属性名可能来自于某个表达式的值,在ES6,可以使用中括号来表示该属性名是通过计算得到的。

let name = "name", age = "age";

const obj = {
    [name]: "abc",
    [age]: 20
}

// 调用
console.log(obj[name])

Object的新增API

1. Object.is

用于判断两个数据是否相等,基本上跟严格相等(===)是一致的,除了以下两点:

  1. NaN和NaN相等
  2. +0和-0不相等
console.log(NaN === NaN);   // false
console.log(+0 === -0)      // true

console.log(Object.is(NaN, NaN))   // true
console.log(Object.is(+0, -0))     // false
2. Object.assign

用于混合对象

const obj1 = {
    a: "1",
    b: "2",
    c: "3"
}

const obj2 = {
    a: "a",
    b: "b",
    d: "d"
}

const obj3 = {
    ...obj1,
    ...obj2
}

const obj4 = Object.assign({}, obj1, obj2)
3. Object.getOwnPropertyNames 的枚举顺序

这个方法之前就存在,只不过官方没有明确要求对属性顺序如何排序,如何排序完全由浏览器厂商自行决定。

ES6规定了该方法返回的数组排序如下:

  • 先排数字,按照升序排序
  • 再排其他,按照书写顺序排序
const obj = {
    d: "1",
    b: "2",
    c: "3",
    0: "A",
    10: "B",
    5: "C"
}
console.log(Object.getOwnPropertyNames(obj))  // ["0", "5", "10", "d", "b", "c"]
4. Object.setPrototypeOf

该方法用于设置某个对象的隐式原型
比如:Object.setPrototypeOf(obj1, obj2) == obj1.__proto__ = obj2

const obj1 = {
    a: "1"
}

const obj2 = {
    b: "2"
}

const obj3 = Object.setPrototypeOf(obj1, obj2)

console.log(obj1 === obj3)  // true

面向对象简介

面向对象:一种编程思想,跟具体的语言

对比面向过程:

  • 面向过程:思考的切入点是功能的步骤
// 大象关进冰箱
// 打开门
function openFridge (params) {
    
}
openFridge()
// 把大象装进去
function putIn() {

}
putIn()
// 把门关上
function closeFridge() {

}
closeFridge()
  • 面向对象:思考的切入点是对象的划分
// 一个冰箱原型
function Fridge() {

}
// 一个大象原型
function Elephant () {
    // 大小,体重,等等
}

// 给冰箱原型增加三个方法
Fridge.prototype.openFridge = function() {
    // 打开冰箱
}

Fridge.prototype.closeFridge = function () {
    // 把冰箱关上
}

Fridge.prototype.putIn = function(ele) {
    // 把什么东西放进去
    
    // -----
    // this.openFridge()      // 打开冰箱
    // this.closeFridge()      // 把冰箱门关上
}

// 调用冰箱原型上的方法

//打开冰箱
let fridge = new Fridge();
fridge.openFridge();

//把大象装进去
let elephant = new Elephant();
fridge.putIn(elephant)

//把冰箱门关上
fridge.closeFridge()
//putIn方法里面的参数可以随意组合,往冰箱里放什么东西都可以,这体现了面向对象写法的好处

面向对象的写法更适合多人开发的大型项目,模块化开发,

类:构造函数的语法糖

传统构造函数的问题
  1. 属性和原型方法定义分离,降低了可读性
  2. 原型成员可以被枚举
  3. 默认情况下,构造函数仍然可以被当作普通函数使用
// 传统写法
function Animal (type, name, age, sex) {
    this.type = type;
    this.name = name;
    this.age = age;
    this.sex = sex;
}
// 给构造函数Animal增加打印方法
Animal.prototype.print = function () {
    console.log(`【种类】:${this.type}`)
    console.log(`【名字】:${this.name}`)
    console.log(`【年龄】:${this.age}`)
    console.log(`【性别】:${this.sex}`)
}

let dog = new Animal("狗", "柴", "3岁", "公")

dog.print()  // 调用原型上的方法
类的特点
  1. 类声明不会被提升,与letconst一样,存在暂时性死区
  2. 类中的所有代码均在严格模式下执行
  3. 类的所有方法都是不可枚举的
  4. 类的所有方法内部都无法被当作构造函数使用
  5. 类的构造器必须使用new使用
// ES6类的写法
class Animal {
    constructor(type, name, age, sex) {
        this.type = type;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    print() {
        console.log(`【种类】:${this.type}`)
        console.log(`【名字】:${this.name}`)
        console.log(`【年龄】:${this.age}`)
        console.log(`【性别】:${this.sex}`)
    }
}

let dog = new Animal("狗", "柴", "3岁", "公")

dog.print()

类的其他书写方式

1. 可计算的成员名
const newProp = "newProp"

class Animal {
    constructor(type, name, age, sex) {
        this.type = type;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    [newProp]() { // 声明
        console.log(`【种类】:${this.type}`)
        console.log(`【名字】:${this.name}`)
        console.log(`【年龄】:${this.age}`)
        console.log(`【性别】:${this.sex}`)
    }
}

let dog = new Animal("狗", "柴", "3岁", "公")

dog[newProp]()   // 调用
2. getter和setter

使用gettersetter定义的属性不在原型上

const newProp = "newProp"

class Animal {
    constructor(type, name, age, sex) {
        this.type = type;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    get age() {  // 获取属性 get
        return this._age
    }

    set age(age) {  // 设置属性 set
        if(age < 0) {
            age = "0"
        } else if(age > 1000) {
            age = "1000"
        }
        this._age = age
    }

    [newProp]() {
        console.log(`【种类】:${this.type}`)
        console.log(`【名字】:${this.name}`)
        console.log(`【年龄】:${this.age}`)
        console.log(`【性别】:${this.sex}`)
    }
}

let dog = new Animal("狗", "柴", "10岁", "公")

dog[newProp]()
3. 静态成员

构造函数本身的成员
使用static关键字定义成员,即静态成员

class box {
    constructor (name) {
        this.name = name;
    }

    static width = 100;

    static height = 100;

    static fn() {
        console.log("这是方法")
    }
}

console.log(box.width)  // 100
console.log(box.height)  // 100

box.fn()  // 调用静态方法
4. 字段初始化器 [ES7]

注意:
1)使用static的字段初始化器,添加的是静态成员
2)没有使用static的字段初始化器,添加的成员位于对象上
3)箭头函数在字段初始化器位置上,指向当前对象

class Test {
    static a = 1
    b = 2
    c = 3
    constructor (){
        // b = 2,  c = 3 相当于
        // this.b = 2
        // this.c = 3
        this.d = this.c + this.b       // 5
    }
}

const t = new Test()

console.log(t)   //Test {b: 2, c: 3}
5. 类表达式

用法和之前的相同

// 匿名类,类表达式
const A = class {  
    b = 2
    c = 3
}

const a = new A()
console.log(a)
6. 装饰器 [ES7]

类的继承

新的关键字:

  • extends:继承,用于类的定义
  • super
    • 直接当做函数调用,表示父类构造函数

      ES6要求,如果定义constructor,并且该类是子类,则必须在constructor的第一行手动调用父类的构造函数

      如果子类不写constructor,则会有默认的构造器,该构造器需要的参数和父类一致,并且自动调用父类构造器

    • 如果当作对象使用,则表示父类的原型

【冷知识】

  • 用JS制作抽象类
    • 抽象类:一般是父类,不能通过该类创建对象
  • 正常情况下this的指向始终指向具体的类的对象
// ES6类的写法
// 父类
class Animal {
    constructor(type, name, age, sex) {
        if (new.target === Animal) {
            throw new TypeError("不能直接创建Animal对象,应该通过子类创建")
        }
        this.type = type;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    print () {
        console.log(`【种类】:${this.type}`)
        console.log(`【名字】:${this.name}`)
        console.log(`【年龄】:${this.age}`)
        console.log(`【性别】:${this.sex}`)
    }
}

// 子类
class Dog extends Animal {
    constructor(name, age, sex) {
        super("犬类", name, age, sex)
        this.hobby = "吃骨头"    // 子类特有属性
    }

    print () {
        super.print()    // 调用父类上的方法
        console.log(`【爱好】:${this.hobby}`)  // 给父类增加一个子类特有方法
    }
}

// let dog = new Animal("柴", "3岁", "公")  // 抛出错误,throw new TypeError("不能直接创建Animal对象,应该通过子类创建")
let dog = new Dog("柴", "3岁", "公")

dog.print()  // 如果子类有这个方法就执行子类的方法,如果子类没有就执行父类的方法。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350