您的位置:首页 > 其它

ES6 class与ES5 function区别及联系

2017-08-24 21:37 471 查看

关于构造器constructor

function
定义的构造函数中,其
prototype.constructor
属性指向构造器自身

class
定义的类中,
constructor
其实也相当于定义在
prototype
属性上

class Point {
constructor() {
// ...这了可以定义实例属性
this.a = 1;
}

toString() {
// ...
}

toValue() {
// ...
}
}

// 等同于

Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};


重复定义

function会覆盖之前定义的方法

class会报错

原型或者类中方法的枚举

class
中定义的方法不可用
Object.keys(Point.prototype)
枚举到

function
构造器原型方法可被
Object.keys(Point.prototype)
枚举到,除过
constructor


所有原型方法属性都可用
Object.getOwnPropertyNames(Point.prototype)
访问到

class Point {
constructor(x, y) {
// ...
}

toString() {
// ...
}
}

Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]


var Point = function (x, y) {
// ...
};

Point.prototype.toString = function() {
// ...
};

Object.keys(Point.prototype)
// ["toString"]
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]


不管是
class
还是
function,constructor
属性默认不可枚举

都可通过实例的__proto__属性向原型添加方法

推荐使用Object.getPrototypeOf()获取实例原型后再添加方法

class没有变量提升

new Foo();
class Foo {}
VM21735:1 Uncaught ReferenceError: Foo is not defined
at <anonymous>:1:1


class定义的类没有私有方法和私有属性

可以用symbol模拟

const bar = Symbol('bar');
const snaf = Symbol('snaf');

export default class myClass{

// 公有方法
foo(baz) {
this[bar](baz);
}

// 私有方法
[bar](baz) {//[bar]用方括号代表从表达式获取的属性名
return this[snaf] = baz;
}

// ...
};


由于bar为symbol值,因此在外面不能当做函数使用。

this指向

class用类似于解构的方式获取原型上的方法

class Logger {
constructor(){}
printName(name = 'there') {
this.print(`Hello ${name}`);
}

print(text) {
console.log(text);
}
}

const logger = new Logger();
const { constructor,print,printName } = logger;


但是执行printName()时,他的this并不是指向当前实例,可在constructor中重新绑定:

constructor() {
this.printName = this.printName.bind(this);
}


class静态方法与静态属性

class定义的静态方法前加static关键字

只能通过类名调用

不能通过实例调用

可与实例方法重名

静态方法中的this指向类而非实例

静态方法可被继承

在子类中可通过super方法调用父类的静态方法

class内部没有静态属性,只能在外面通过类名定义。

new.target

new target属性指向当前的构造函数,不能在构造函数外部调用会报错,

function Person(name) {
console.log(new.target);
if (new.target !== undefined) {
this.name = name;
} else {
throw new Error('必须使用new生成实例');
}
}
测试:
Person(123)
undefined
Uncaught Error: 必须使用new生成实例


2.继承时new.target返回子类

class Rectangle {
constructor(length, width) {
console.log(new.target === Rectangle);
// ...
}
}

class Square extends Rectangle {
constructor(length) {
super(length, length);
}
}

var obj = new Square(3); // 输出 false


可构造不能被实例化的类,只能通过继承发挥作用:

class Shape {
constructor() {
if (new.target === Shape) {
throw new Error('本类不能实例化');
}
}
}

class Rectangle extends Shape {
constructor(length, width) {
super();
// ...
}
}

var x = new Shape();  // 报错
var y = new Rectangle(3, 4);  // 正确
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: