遍历代码:
- 类被定义为使用提供的参数调用 init 的函数。这意味着您可以使用
new
例如标准构造函数语法调用它。var instance = new Thingy()
并获取使用正确值init
调用的函数。this
- 如果你传入一个父类,你的类会将该类的
prototype
属性添加到一个新的空对象的原型链中,并将其用作其 prototype
属性。在现代浏览器中执行此操作的一种更简洁的方法是_class.prototype = Object.create(parent.prototype);
- 功能已
init
定义。这可能会在创建实例后被更有用的初始化代码覆盖_class
(或者应该更改代码以允许在init
创建类时传入函数......或允许实例遍历原型链以查找其他init
功能。
_class.fn
创建它是为了提供对_class
构造函数的原型函数的引用。
_class.fn.parent
被创建以提供对构造函数的引用。如果您在其他上下文中应用原型并希望引用回原型的构造函数,这可能很有用。
_class._super
被分配了构造函数的内部非标准__proto__
属性。请记住,构造函数是函数,而在 Javascript 中,函数是对象。这意味着他们有自己的内部原型。较早的引用prototype
是分配给使用此构造函数创建的对象的原型,而不是构造函数的原型本身。所有函数都从 Function.prototype 继承,这是它们获取bind
,apply
等的地方。_super
在这种情况下,它只是对 的引用Function.prototype
。
至于何时_super
使用这种类型,可以想象执行以下操作:
function Maker(){ //this will be called as a constructor, ie. with new
var fun = function(){}; //Make a function
fun.__proto__ = this.__proto__; //yuck. Set the function's this value to the instance
return fun; //return the function
}
Maker.prototype={say:function(){console.log("Javascript is fun!.. And weird.")}};
var fun = new Maker();
fun.say() //"Javascript is fun!.. And weird."
console.log(fun.__proto__) // Object{say:function}
console.log(fun.bind) // undefined!!
哇!刚才发生了什么?事实上,你用一个对象替换了你的函数内部原型。这使您可以构建有趣的原型链并以类似的方式与函数和对象进行交互。但是请注意,与 的链接Function.prototype
已被切断,这就是我们无法访问bind
. 然而,让我们用更多的原型魔法来修复它!
function FunctionConnector(obj){
for (var prop in obj){
if(obj.hasOwnProperty(prop){
this.prop=obj.prop
}
}
}
FunctionConnector.prototype=Function.prototype;
Maker.prototype=new FunctionConnector({say:function(){
console.log("Javascript is fun!.. And weird.")
}});
var fun = new Maker();
fun.say() //"Javascript is fun!.. And weird."
console.log(fun.__proto__) // Object{say:function}
console.log(fun.bind) // function bind(){ [native code] }
现在那是什么FunctionConnector
?它接受一个对象,当作为构造函数调用时,返回一个对象,该对象既具有传递对象的所有属性,又继承自Function.prototype
. 如您所见,我们的访问权限bind
已经返回(当然,我们也可以使用我们最初的实现,并Function.prototype.bind.call
为胜利铺平道路)。
有了这个新模式,您的代码中的功能可能会更清楚_super
,即它引用了您正在制作的构造函数的内置原型_class
(在我们的示例中,实例FunctionConnector
将是_super
)。此引用可用于在运行时修补原型,调用方法apply
或其他任何您可以通过引用对象获得的东西。
正如您可能已经注意到的那样,这有点骇人听闻,尤其是因为__proto__
它是非标准的。但如果你喜欢它允许的模式,它也有点整洁。如果您对 Javascript 继承的知识非常有信心,我建议您只做这样的事情,除非您负责您的整个代码库,否则甚至可能不这样做。