为毛要用 prototype,这货是对象?

自从自愿踏上 JavaScript 这首贼船,prototype 就在我身边阴魂不散。真不知道是哪个二货设计了 prototype chain 这个模式,居然用这么奇葩的方式来实现继承。对于远古圣人的这种设计思想,我表示很尊重,真相永远只有一个!

JavaScript、Java、JavaScript、Java……

对,就像你看到的一样,JavaScript 和 Java 之间有过不堪回首的基情。当时的设计者 Michael Scofield 失散多年的哥哥 Brendan Eich 不惧 Sun 公司的威逼,坚决不将 OOP 引入 JavaScript;但是在 Sun 公司的利诱下艰难的把 new 命令引入到了 JavaScript中。

new,中看不中用

由于 Sun 公司不够意思,所以 Big Fish 也只是意思意思。在 JavaScript 中,new 后面跟的根本就不是类,只是构造函数而已(毛用没得,完全不能继承啊)。当你 new 一个类的时候,该类的实例会自动生成一个 constructor 属性,指向你定义的构造函数。所以呢,继承呢?对,这只是构造……

1
2
3
4
5
6
7
8
Language (name) ->
	@name = name

js = new Language("javascript")
java = new Language("java")

console.info(js.constructor is Language) // true
console.info(java.constructor instanceof Language) // true

prototype 出现了

Sun 公司发现被坑了后,非常气愤。立马对 Brendan Eich 进行了各种糖衣炮弹的合理围攻,终于使我们威武雄壮的 Scofield 的哥哥再一次做出了一个艰难的决定:给所有 JavaScript 类(不是实例),增加一个

在类上增加一个类,内部类?匿名内部类?哎呀,这是咋回事啊!当然不是咯,为了减少紧缺资源的占用。Fish 规定每一个构造函数都有一个 prototype 属性,她指向一个对象,这个对象的所有东东都会被构造函数的实例共享。 因此所有实例在默认情况下都有一个原型(prototype)。

1
2
3
4
5
function Foo() {};
var foo = new Foo();
Foo.prototype.label = "sconfield";
alert(Foo.label); //output: undefined
alert(foo.label); //output: sconfield

arguments

等会在忽悠!

滚粗

小米发布会终于听完了,以上内容不管你信不信,反正我编的!