es6对象总结

1 class简介

  通过传统的构造函数生成对象

function Point({name,age,tall}) {
    this.name = name;
    this.age = age;
    this.tall = tall
}

Point.prototype.toString = function ()  {
   return `${this.name},${this.age},${this.tall}`
}

const Point1 = new Point({name:"张三" , age:24, tall:173});
console.log(Point1);
console.log(Point1.toString());


Point { name: '张三', age: 24, tall: 173 }
张三,24,173

es6 通过class关键字创建对象


class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}

const Point4 = new Point2({name:"小张" , age:20, tall:180});
console.log(Point4);
console.log(Point4.toSoring());

Point2 { name: '小张', age: 20, tall: 180 }
小张,20,180

通过class创建的类里面存在一个constructor构造方法。this关键字代表实利对象。 简而言之es5的Point构造代表es6中Point的构造方法, Point除了构造方法之外还定义了toSoring方法。  值得注意的是在定义类的方法时是不需要加function关键字的直接定义函数即可。此外方法与方法之间是不需要加逗号分隔的,

es6的类可以看到是构造函数的另一种写法。即类的数据类型本身就是函数。而类本身指向构造函数

console.log(typeof Point2);
console.log(typeof Point2 === typeof Point2.prototype.constructor);

function
true

构造函数的prototype属性在es6上仍然存在。 实际上类的所以上传都是定义在类的prototype上。


class Point5 {
    constructor({}){}
    toSoring(){}
}
// 等同于
Point5.prototype = {
    constructor(){},
    toSoring(){}
};

在实利上调用方法就是在原型上调用方法


class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}

console.log(Point4.toSoring === Point2.prototype.toSoring)

true

由于类的方法都定义在prototype上。故可以通过Object.assign()一次性添加多个新的方法

class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}

Object.assign(Point2.prototype,{
    toValue(){
        return this.name
    },
    getAge(){
        return this.age
    }
})

const Point4 = new Point2({name:"小张" , age:20, tall:180});
console.log(Point4.toValue())
console.log(Point4.getAge())

小张
20

prototype属性的constructor的属性指向类本身。 这点与es5相同

console.log(Point2.prototype.constructor === Point2)

true

类内部定义的方法是不可枚举的。 

对枚举的说明

1。for - in 会遍历对象里可枚举的属性。包括自有属性和继承属性

2。可以通过Object.keys()会返回自有的可以枚举属性组成的数组

3。Object.getOwnPropertyNames()会返回自有的属性名。可枚举和不可枚举都会返回

class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}

Object.assign(Point2.prototype,{
    toValue(){
        return this.name
    },
    getAge(){
        return this.age
    }
})

console.log(Object.keys(Point2.prototype));
console.log(Object.getOwnPropertyNames(Point2.prototype))

[ 'toValue', 'getAge' ]
[ 'constructor', 'toSoring', 'toValue', 'getAge' ]

二。constructor

constructor方法是类的默认方法。 通过new实利对象时会自动调用这个方法。一个类必须包含constructor方法。 即使没有显示的添加也会有一个空的constructor被添加。constructor方法默认会返回实利对象(this),但是可以指定返回特定的对象

class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}


const Point4 = new Point2({name:"小张" , age:20, tall:180});
console.log(Point4)

class Class1 {
    constructor() {
        return {}
    }
}

let a = new Class1();
console.log(a);


class Class2 {
    constructor() {
        return Object.create(null)

}
}

let b = new Class2();
console.log(b);

Point2 { name: '小张', age: 20, tall: 180 }
{}
[Object: null prototype] {}

三。类的实例

类必须通过new调用 ,否则会报错。 这也是和普通函数的区别。

class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}


const Point4 = Point2({name:"小张" , age:20, tall:180});
console.log(Point4)

TypeError: Class constructor Point2 cannot be invoked without 'new'

与es5一样实例的属性除非显示的定义在其类本身即this对象上。否则都会定义在原型上即class上


class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}

const Point4 = new Point2({name:"小张" , age:20, tall:180});
console.log(Point4.hasOwnProperty('name'));
console.log(Point4.hasOwnProperty("age"));
console.log(Point4.hasOwnProperty("toSoring"));
console.log(Point4.__proto__.hasOwnProperty("toSoring"))

true
true
false
true

与es5一样类的实例共享同一个原型对象。他们的原型对象都是Point2.prototype

class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}


const Point4 = new Point2({name:"小张" , age:20, tall:180});
const Point5  = new Point2({name:"小王", age:28, tall:173});
console.log(Point4.__proto__ === Point5.__proto__)

true

这就意味着可以通过__proto__为类添加新的方法。 值得注意的是这样做以后所以的实例对象都可以调用这个方法。并且__proto__并不是编程语言本身的特性。 故不推荐使用

class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
}

const Point4 = new Point2({name:"小张" , age:20, tall:180});
Point4.__proto__.add = function () {
    console.log("这是通过原型对象添加的方法")
};
Point4.add();
const Point5  = new Point2({name:"小王", age:28, tall:173});
Point5.add();

这是通过原型对象添加的方法
这是通过原型对象添加的方法

四, 取值函数(getter)和存值函数(setter)

与es5一样可以通过get函数读取属性和设置属性

class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    toSoring(){
        return `${this.name},${this.age},${this.tall}`
    }
    get prop(){
        return this.name
    }
    set prop(value){
        this.age = value
    }
}


const Point4 = new Point2({name:"小张" , age:20, tall:180});
console.log(Point4.prop);
Point4.prop = 30;
console.log(Point4);

小张
Point2 { name: '小张', age: 30, tall: 180 }

五。 属性表达式。 类的属性可以使用表达式


let toSoring = 'toSoring';
class Point2 {
    constructor({name,age,tall}) {
        this.name = name;
        this.age = age;
        this.tall = tall
    }
    [toSoring](){
        return `${this.name},${this.age},${this.tall}`
    }
}



const Point4 = new Point2({name:"小张" , age:20, tall:180});
console.log(Point4.toSoring())

小张,20,180

六。类表达式  要注意的是类名只能在类的内部使用

let myClass = class Class {
    constructor() {
        this.age = 23
    }
    getData(){
        return Class.name
    }
};


let a = new myClass();
console.log(a.getData());
console.log(Class.name)

Class
ReferenceError: Class is not defined

类名在其内部没有使用到则可以简写

let myClass = class {};

利用类的表达式可以定义立即执行的类

let a = new class{
    constructor() {
        this.name = "小张"
    }
};
console.log(a.name);

小张

七。静态方法

类的方法前面加上static关键字表示该方法为静态方法不会被继承。通过类直接调用。且静态方法中包含this时你在指向实例而是指向类本身


 class Class {
    constructor() {
        this.age = 23
    }
    getData(){
        return Class.name
    }
    static add(){
        this.add1()
    }
    static add1(){
        console.log("这是静态方法")
    }
};


let a = new Class();
Class.add();
a.add()


这是静态方法
TypeError: a.add is not a function

父类的静态方法可以被子类继承

 class Class {
    constructor() {
        this.age = 23
    }
    getData(){
        return Class.name
    }
    static add(){
        this.add1()
    }
    static add1(){
        console.log("这是静态方法")
    }
};


let a = new Class();

class Class1 extends Class {}

let b = new Class1();
Class1.add()

这是静态方法

八。实例属性的新写法


class number {
    constructor() {
        this.number = 0
    }
    geyNumber(){
        return this.number
    }
    instNumber(){
        this.number ++
    }
}


class number1 {
    number = 0;
    geyNumber(){
        return this.number
    }
    instNumber(){
        this.number ++
    }
}

九。静态属性


class B {}
B.name = "小张";
console.log(B.name);
let a = new B();
console.log(a.name);

B
undefined
发布了26 篇原创文章 · 获赞 79 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_25502269/article/details/105351650