最近我开始学习更高级的JavaScript(至于我只使用jQuery执行一些简单的任务)并购买了一本Alex MaxCaw“JavaScript Web Applications”一书。第一章讨论创建简单的类模拟器。我理解几乎所有的东西,除了下面标有评论的两行代码:
var Class = function(parent) {
var _class = function() {
this.init.apply(this, arguments);
};
if(parent) {
var subclass = function() {};
subclass.prototype = parent.prototype;
_class.prototype = new subclass();
};
_class.prototype.init = function() {};
_class.fn = _class.prototype;
//????
_class.fn.parent = _class;
//????
_class._super = _class.__proto__;
return _class;
};
谁能告诉我这两行的目的是什么?我会非常感激的。
答案 0 :(得分:3)
浏览代码:
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!!
哇!刚刚发生了什么?
实际上,您使用Object替换了函数内部原型。这允许您构建有趣的原型链,并以类似的方式与功能和对象进行交互。但请注意,与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
构造函数的内置原型(在我们的例子中是{的实例{1}}将是FunctionConnector
)。此引用可用于在运行时修补原型,使用_super
调用方法,或者通过引用对象调用其他任何内容。
这是因为你可能已经注意到有点hackish,特别是因为apply
是非标准的。但如果你喜欢它允许的模式,它也有点整洁。如果你对Javascript继承的知识非常有信心,我建议你只做这样的事情,除非你负责你的整个代码库,否则我甚至不会这样做。
答案 1 :(得分:-1)