第四章:原型与继承,class下的秘密
下午茶过后,三人从小卖部回到实验室,手里还拎着几瓶冰镇饮料。天气虽然不算炎热,但在没有空调的机房里,口渴是常态。
林雨菲打开笔记本,笑盈盈地问道:“苏澈,你刚才说要给我们讲讲 class 语法糖是怎么回事?”
赵大海一边猛灌饮料,一边插嘴:“对对,我也想知道。之前看过点 ES6 的东西,知道可以用 class 来写面向对象,看起来挺优雅,但听人说这其实就是个语法糖?”
“没错。”苏澈点点头,“为了理解 class,我们先得弄懂 JavaScript 的原型继承机制。”
他随手敲下一段最传统的构造函数写法:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, I\'m ' + this.name);
};
var p1 = new Person('Alice');
p1.sayHello(); // Hello, I'm Alice
“这里的 Person 就是一个构造函数,Person.prototype 里定义的方法,会被所有基于 Person 创建的实例共享。”
林雨菲恍然:“所以 Person.prototype 是所有实例的公共祖先?”
“可以这么理解。不过更本质的说法是,每个对象在内部都有一个 __proto__ 指针,指向它的原型。new Person() 出来的实例,__proto__ 会指向 Person.prototype。”
赵大海挠挠头:“那 Object.create() 呢?我见过有人用它来做继承。”
“对,Object.create(proto) 可以以指定对象为原型,创建一个新的对象,稍微演示一下吧。”
苏澈又写了一段示例:
var animal = {
canRun: true,
run: function() {
console.log('I can run!');
}
};
var dog = Object.create(animal);
console.log(dog.canRun); // true
dog.run(); // I can run!
“在这里,dog 的 __proto__ 指向 animal,因此可以访问 animal 里的属性和方法,这也是一种原型继承。”
林雨菲微笑道:“原来如此。这就解释了为什么 JavaScript 不像传统的面向对象语言那样有‘类’,它本质是基于原型链来实现继承的。”
苏澈打了个响指:“没错!那么 ES6 引入的 class 其实就是在语法层面包装了一层,让你可以用类似 Java、C# 那样的面向对象写法,更符合某些开发者的习惯。但本质上,还是走的原型链那一套。”
“快写个 class 试试?”赵大海显得迫不及待。
“好嘞。”苏澈又敲键盘:
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello, I'm ${this.name}`);
}
}
let p2 = new Person('Bob');
p2.sayHello(); // Hello, I'm Bob
console.log(p2.__proto__ === Person.prototype); // true
“看,最终还是 p2.__proto__ === Person.prototype。”
林雨菲边看边点头:“的确是语法糖。那关于继承呢?class 里面用 extends 也可以做继承,对吧?”
“当然,extends 相当于以前的 Child.prototype = Object.create(Parent.prototype) plus 一些额外处理,让你写起来更顺手。”
赵大海摸了摸下巴:“我以前还真以为 class 是个新概念,没想到底层是原型链。”
“很多人都会误以为 JavaScript 和传统的 OOP 语言一样,其实差别还挺大。”苏澈看着屏幕,“不过学好这些,对做大型项目乃至造一些新东西都很有帮助。”
林雨菲点头:“确实,我一直觉得前端要想做得好,还是得深入理解 JS 的底层机制。”
“等有机会,我们可以试着做个小型的 MVVM 项目,把这些概念都用上。”苏澈微微一笑,“这样大家实践起来,也会更有感觉。”
赵大海兴奋地搓手:“嘿,那就赶紧行动啊,我迫不及待想搞点新鲜玩意儿了!”
“别急,我们先打好基础。”苏澈拍了拍赵大海的肩膀,“你看,短短两天,你已经从一个只会打游戏的咸鱼,变成了闭包和 this 都略知一二的技术新人了。”
“去,你才咸鱼!”赵大海翻了个白眼。
三人相视一笑,气氛里充满了对未来的期待。
深夜时分
三个人还留在实验室,围着几台电脑,除了学习,也在讨论一些对前端的见解。林雨菲偶尔提起她对算法的理解,赵大海则津津乐道地谈起自己对游戏界面的“UI交互”构想。
苏澈一边笑,一边心想:
“回到2014年,一切才刚开始。既然我已经重新踏上这条路,就绝不会再像上辈子那样被动。等我学牢了这些JS底层,再来实现更强大的想法。”
窗外夜色渐浓,但他们的热情却丝毫没有减退。没人注意到,一段属于他们的传奇,也许已经悄悄拉开了帷幕……