持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
class
类的数据类型就是函数,类本身就指向构造函数。
typeof Point // "function"
Point === Point.prototype.constructor // true
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
// 等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};
new.target
new.target会返回类实例本身。 需要注意的是
-
new.target只有通过new关键字或者Reflect.construct()创建的实例new.target才会返回class本身。 否则返回undefined -
子类
new.target返回子类名称。
①利用以上特点可以判断类是否new 实例化的
class Person {
constructor(props) {
if (new.target === 'undefined') {
throw new Error('必须通过new来实例化对象');
}
}
}
②创建只能用来继承的类
class Shape {
constructor() {
if (new.target === Shape) {
throw new Error('本类不能实例化');
}
}
}
遍历对象
ES6 一共有 5 种方法可以遍历对象的属性。
(1)for…in
for...in循环遍历对象***自身的和继承***的可枚举属性(不含 Symbol 属性)。
(2)Object.keys(obj)
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
es5和 es6一些区别
1.实例方法都是在原型上的(es5和 es6都一样)
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
this.testFunction = this.test
}
c = '222'
static __run() {
console.log('__run')
}
test(){
console.log('333')
}
toString() {
return '( x:' + this.x + ', y:' + this.y+ ', c:' + this.c + ')';
}
}
// super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
// super对某个属性赋值,这时super就是this
class Bar extends Point {
constructor() {
super();
// super
super.test()
}
static classMethod() {
return super.__run() + ', too';
}
draw() {
super.test()
// super对某个属性赋值,这时super就是this
super.x = 3;
console.log(this.x); // 3
}
}
// 可以通过实例的__proto__属性为“类”添加方法。
var point = new Point(2, 3);
point.__proto__.functionName = function () {}
上述执行后的实例
静态方法在 new 出来的实例上是不存在的,只能用类名直接调用, 子类静态方法可以通过 super.父类静态方法名 来调用父类静态方法 es6 只有静态方法,没有静态属性,静态属性只能通过 className.prop = value来定义
super()实际上就是调用父类的构造函数
2. 继承的实现
- es5 中实现继承
const child = new Child()
Parent.apply(child)
- es6中
class Child extends Parent{
constructor() {
super()
}
}
es6 直接是子类构造方法中调用
super()(实际相当于new Parent()),因为在子类构造方法,所以直接加载到了子类this上了。实际相当于在子类构造方法里面调用了parent.prototype.constructor.call(this)子类实例创建是基于父类实例,所以必须在super()后才可以用 this 关键字
Object.getPrototypeOf(Child) === Parent 从子类中获取父类实例。 用来判断继承关系
class A {
}
class B extends A {
}
A.__proto__ === Function.prototype // true
A.prototype.__proto__ === Object.prototype // true
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
// 子类B的__proto__属性指向父类A,子类B的prototype属性的__proto__属性指向父类A的prototype属性
继承可以实现对原生类的扩展比如 Array。 但是继承 Object 特殊,无法传参给 Object