您的位置:首页 > 其它

ES6------Class继承

2017-12-23 00:00 525 查看
摘要: 继续加油。

资料源:http://es6.ruanyifeng.com/#docs/class-extends

算是入门了

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

<!--加载 Traceur-->
<script type="text/javascript" src="traceur.js"></script>
<!--将Traceur文件用于浏览器环境-->
<script type="text/javascript" src="BrowerSystem.js"></script>
<script type="text/javascript" src="bootstrap.js"></script>

<script type="module">

// 1.Class 可以通过extends关键字实现继承

// 子类必须在constructor方法中调用super方法
// 否则新建实例时会报错

// 子类没有自己的this对象,
// 而是继承父类的this对象,
// 然后对其进行加工。
// 如果不调用super方法,子类就得不到this对象

// 子类实例的构建,是基于对父类实例加工,
// 只有super方法才能返回父类实例。

class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}

class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y);    // super表示父类的构造函数,用来新建父类的this对象
this.color = color;
}

toString() {
return this.color + ' ' + super.toString();
}
}

let p = new ColorPoint(1, 2, 'red');
console.log(p);
console.log(p instanceof ColorPoint);
console.log(p instanceof Point);

// 2.父类的静态方法,也会被子类继承
class A {
static hello() {
console.log('hello world');
}
}

class B extends A {

}
B.hello();

// 3.Object.getPrototypeOf方法可以用来从子类上获取父类
// 可以使用这个方法判断,一个类是否继承了另一个类
console.log(Object.getPrototypeOf(ColorPoint) === Point);

// 4.super作为函数调用时,代表父类的构造函数。
// ES6 要求,子类的构造函数必须执行一次super函数
// 返回的是子类B的实例,即super内部的this指的是B,
// 因此super()在这里相当于A.prototype.constructor.call(this)
// 作为函数时,super()只能用在子类的构造函数之中,用在其他地方就会报错
class A {
constructor() {
console.log(new.target.name);
}
}

class B extends A {
constructor() {
super(); // 代表父类的构造函数
}
}
console.log(new A());
console.log(new B());   // super()内部的this指向的是B。

// 5.super作为对象时,在普通方法中,指向父类的原型对象;
// 在静态方法中,指向父类。

class A {
p() {
return 2;
}
}

class B extends A {
constructor() {
super();
console.log(super.p()); // super.p()就相当于A.prototype.p()
}
}
let b = new B();

// 6.由于super指向父类的原型对象,
// 所以定义在父类实例上的方法或属性,是无法通过super调用的

class A {
constructor() {
this.p = 2;
}
}

class B extends A {
get m() {
return super.p;
}
}

let b = new B();
console.log(b.m);

// 7.属性定义在父类的原型对象上,super就可以取到

class A {}
A.prototype.x = 2;
class B extends A {
constructor() {
super();
console.log(super.x);
}
}
let b = new B();

// 8.通过super调用父类的方法时,方法内部的this指向子类

class A{
constructor() {
this.x = 1;
}

print() {
console.log(this.x);
}
}

class B extends A {
constructor() {
super();
this.x = 2;
}

m() {
super.print();
}
}

let b = new B();
b.m();

// 9.通过super对某个属性赋值,
// 这时super就是this,
// 赋值的属性会变成子类实例的属性。
class A {
constructor() {
this.x = 1;
}
}

class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x);   // super其实就是子类的this
console.log(this.x);
}
}

let b = new B();

// 10.super作为对象,用在静态方法之中,
// 这时super将指向父类,而不是父类的原型对象。
class Parent {
static myMethod(msg) {
console.log('static', msg);
}

myMethod(msg) {
console.log('instace', msg);
}
}

class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);    // super在静态方法之中指向父类
}

myMethod(msg) {
super.myMethod(msg);    // 在普通方法之中指向父类的原型对象
}
}

Child.myMethod(1);

var child = new Child();
child.myMethod(2);

// 11.使用super的时候,必须显式指定是作为函数、还是作为对象使用
class A {

}
class B extends A {
constructor() {
super();        // 函数
console.log(super.valueOf() instanceof B); // 对象
}
}

let b = new B();

// 12.由于对象总是继承其他对象的,
// 所以可以在任意一个对象中,使用super关键字
var obj = {
toString() {
return 'MyObject: ' + super.toString();
}
};

console.log(obj.toString());

// 13.Class 作为构造函数的语法糖,
// 同时有prototype属性和__proto__属性,
// 因此同时存在两条继承链。

// (1)子类的__proto__属性,
// 表示构造函数的继承,总是指向父类。

//(2)子类prototype属性的__proto__属性,
// 表示方法的继承,总是指向父类的prototype属性。

// 作为一个对象,
// 子类(B)的原型(__proto__属性)是父类(A);
// 作为一个构造函数,
// 子类(B)的原型对象(prototype属性)是父类的原型对象(prototype属性)的实例。

class A {

}
class B extends A {

}

console.log(B.__proto__ === A);
console.log(B.prototype.__proto__ === A.prototype);

// 14.子类继承Object类
// A其实就是构造函数Object的复制,
// A的实例就是Object的实例。
class A extends Object {

}
console.log(A.__proto__ === Object);
console.log(A.prototype.__proto__ === Object.prototype);

// 15.不存在任何继承
class A {

}
console.log(A.__proto__ === Function.prototype);
console.log(A.prototype.__proto__ === Object.prototype);

// 16.子类继承null
class A extends null {

}
console.log(A.__proto__ === Function.prototype);
console.log(A.prototype.__proto__ === undefined);

// 17.子类的原型的原型,是父类的原型。
var p1 = new Point(2, 3);
var p2 = new ColorPoint(2, 3, 'red');

console.log(p2.__proto__ === p1.__proto__);
console.log(p2.__proto__.__proto__ === p1.__proto__);

// 18.通过子类实例的__proto__.__proto__属性,
// 可以修改父类实例的行为。
p2.__proto__.__proto__.printName = function () {
console.log('hello');
}
p1.printName();

// 19.原生构造函数
/*
*   Boolean()
Number()
String()
Array()
Date()
Function()
RegExp()
Error()
Object()
*
* */

// 20.ES6 允许继承原生构造函数定义子类
// extends关键字不仅可以用来继承类,
// 还可以用来继承原生的构造函数
class MyArray extends Array {
constructor(...args) {
super(...args);
}
}

var arr = new MyArray();
arr[0] = 12;
console.log(arr.length);
arr.length = 0;
console.log(arr[0]);

// 21.Mixin 指的是多个对象合成一个新的对象,
// 新对象具有各个组成成员的接口。
function mix(...mixins) {
class Mix {}

for(let mixin of mixins) {
// 拷贝实例属性
copyProperties(Mix, mixin);
// 拷贝原型属性
copyProperties(Mix.prototype, mixin.prototype);
}

return Mix;
}

function copyProperties(target, source) {
for(let key of Reflect.ownKeys(source)) {
if(key !== 'constructor' && key !== 'prototype' && key !== 'name'){
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
}

console.log(mix());

</script>

</head>
<body>

<h1>hello</h1>

</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: