为毛要用 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
等会在忽悠!
滚粗
小米发布会终于听完了,以上内容不管你信不信,反正我编的!