【ES6】Class
以前采取构造函数+原型创建类
function Point(x, y) { }
Point.prototype.fn = function () { }
let p = new Point(1,2)
ES6使用class声明类
- 定义类的方法不用function关键字,方法之间不用逗号分隔
- 类内部采取严格模式,类不存在变量提升
- name属性 Point.name===Point
- 类内部this默认指向类的实例
class Point {
// 实例方法 p.exampleProp
exampleProp = "实例属性"
// constructor方法是类的默认方法,通过new命令生成实例对象自动调用该方法
// 没有显示定义会默认添加一个空的constructor
// constructor方法默认return实例对象即this
// Point.prototype.constructor === Point
constructor(x, y) {
this.x = x
this.y = y
console.log(this.x,this.y)
}
// 类内部使用get,set关键字对某个属性设置存执函数和取值函数拦截该属性的存取行为
// 其行为定义在Point.prototype上
// Object.getOwnPropertyDescriptor(Point.prototype,'prop')
get prop() { console.log('getter') }
set prop(val) { console.log('setter: ' + val); }
// 类的方法直接定义在Point.prototype上,但是是不可遍历的
fn() { }
// 静态属性和静态方法,不会被实例继承,直接通过类来调用如Point.staticProp。会被继承
static staticProp = '静态属性'
static staticMethod() { }
// 私有属性和方法,只能在类的内部访问,外部部分访问
#privateProp = "私有属性,只能在类的内部访问,外部无法访问"
_privateMethod() { }
}
let p = new Point(1, 2) // 生成实例对象
p.__proto__ === Point.prototype === Object.getPrototypeOf(p)
new.target
- 在构造中调用,如果不是通过new命令或者Reflect.constructor()调用,new.target会返回undefined
function Person(name) {
if (new.target === Person) {
this.name = name;
} else {
throw new Error('必须使用 new 命令生成实例');
}
}
var person = new Person('张三'); // 正确
var notAPerson = Person.call(person, '张三'); // 报错
- class内部调用new,target,返回当前class
- 子类继承父类,new.target会返回子类
class Rectangle {
constructor(length, width) {
console.log(new.target === Rectangle);
// ...
}
}
class Square extends Rectangle {
constructor(length, width) {
super(length, width);
}
}
var obj = new Square(3); // 输出 false
- 可以构建不能独立使用、必须继承后才能使用的类,即在父的constructor中做判断,如果new.target为Father则抛出错误
继承
使用extends继承
class Father {
constructor(x, y) {
this.x = x
this.y = y
}
}
class Children extends Father {
constructor(x, y, z) {
// super()在这里表示父类构造函数,必须在constructor方法中调用super()
// 如果不调用supe方法,子类就得不到this对象
// 子类自己的this对象必须通过父类的构造函数塑造,得到与父类同样的实例属性和方法,然后再进行加工,加上子类自己的实例属性和方法
super(x, y) //相当于Father.prototype.constructor.call(Children)
this.z = z
}
// super()作为函数只能在子类constructor方法中出现
// 作为对象可以在子类普通方法中出现,指向父类的原型对象Father.prototype
// 在静态方法中,指向父类
}
Object.getPrototypeOf(Children) === Father
__proto__
每个对象都有__proto__属性,指向对应的构造函数的原型。Class作为构造函数的语法糖,同时存在两条继承链
- 子类的__proto__属性,表示构造函数的继承,总是指向父类
- 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性
class A { }
class B extends A { }
B.__proto__ === A
B.prototype.__proto === A.prototype
类的继承是按照下面的模式实现的
class A { }
class B { }
Object.setPrototypeOf(B.prototype, A.prototype) //B实例继承A实例
Object.setPrototypeOf(B, A); //B继承A的静态属性

浙公网安备 33010602011771号