小爝(知乎用户):js里面什么都是对象,所以你看单身狗学这个语言学的老快了。

就前几天看到的答案,觉得对啊!js这种边缘OP的语言,你说它没对象它是可以有的,你说它是面向对象语言它不是。
所以来研究一手关于JavaScript的继承。研究过程用一下typescript(这个真有对象了)

先看一下关于typescript的继承

看一下ts的类

1
2
3
4
5
6
7
8
9
10
11
class Parent {
name: string
age: number
constructor(msg:string, age:number) {
this.age = age
this.name = msg;
}
sayHello() {
return console.log(`hello ${this.name},now is ${this.age}`)
}
}

然后来一手调用,全程感觉像在用java

1
2
let par = new Parent("mike", 16)
par.sayHello() //hello mike,now is 16

答案我在terminal验证过的没问题!!

接下来尝试一下如果我走继承会是什么样,来一手继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Parent {
name: string
age: number
constructor(msg:string, age:number) {
this.age = age
this.name = msg;
}
sayHello() {
return console.log(`hello ${this.name},now is ${this.age}`)
}
}
//Now extends.
class Son extends Parent {
constructor(msg, age) {
super(msg, age);
}
sayHello() {
console.log(`hello I'm Son. next is my Parent's say`)
super.sayHello()
}
}

来手调用验证结果

1
2
let sapi = new Son('peanut', 10)
sapi.sayHello() //hello I'm Son. next is my Parent's say\n hello peanut,now is 10

该研究JavaScript的继承了

先来看一下第一个例子翻译成ES5(JavaScript)是什么样的

1
2
3
4
5
6
7
8
9
10
11
12
var Parent = (function () {
function Parent(msg, age) {
this.age = age;
this.name = msg;
}
Parent.prototype.sayHello = function () {
return console.log("hello " + this.name + ",now is " + this.age);
};
return Parent;
}());
var par = new Parent("mike", 16);
par.sayHello();

首先是建立了个函数,函数内再嵌套一层函数,然后通过内部的prototype添加一个方法,最后返回整个父函数。
燃鹅在这个函数内部已经做了一次叫“原型链继承”的事情了。就是从父级,或者说从其他原型来指向到继承的实例来达到元素一并继承,这样我要实现后面的实例的时候就要连带前面的也一并执行了。

然后第二个例子,多了个继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Parent = (function () {
function Parent(msg, age) {
this.age = age;
this.name = msg;
}
Parent.prototype.sayHello = function () {
return console.log("hello " + this.name + ",now is " + this.age);
};
return Parent;
}());
var Son = (function (_super) {
__extends(Son, _super);
function Son(msg, age) {
return _super.call(this, msg, age) || this;
}
Son.prototype.sayHello = function () {
console.log("hello I'm Son. next is my Parent's say");
_super.prototype.sayHello.call(this);
};
return Son;
}(Parent));
var sapi = new Son('peanut', 10);
sapi.sayHello();

有点厉害,我先坐下来……

先是构造了个链子,然后(那个是闭包污染处理嘛…)…… 说不清了……

反正看子类,很明显在“Son类”结束前,有一个(Parent),虽说ts对于类的处理都是一个大个的及时运行函数,但是"parent"运行时并没有带参数,而"Son"带了它的爹,如果我的理解的是对的的话,就是"Son"在运行的时候把"Parent"带着运行一次起到“继承”的效果。最后还是照原型链的理解。

关于JavaScript的其他继承

还是因为我的爬虫小记中的现世界宝可梦数量及其名字的项目中,用到了.call(this)这个函数句。所以在想,是否可以使用构造函数走一波继承?

1
2
3
4
5
6
function a() {
return console.log('this is a')
}
function b() {
a.call(this)
}

然后调用

1
b()     //this is a

所以也是可以的。结束!