2009-12-06 109 views
0

我尝试创建一些基于类的jQuery风格,如下面的代码。为什么jQuery使用“new jQuery.fn.init()”来创建jQuery对象,但我不能?

myClass = window.myClass = function(x, y) 
{ 
    return new myClass.fn.init(x, y); 
}; 

myClass.fn = myClass.prototype = 
{ 
    init: function(x, y) 
    { 
     // logic for creating new myClass object. 
    } 
}; 

我不明白为什么jQuery的使用new关键字,因为从我的实验创建它的类,JavaScript的始终创建myClass.init对象,而不是MyClass的对象。但是,我尝试删除myClass构造函数中的新关键字。但它仍然没有改变。你能解释为什么jQuery可以做到这一点,但我不能或给我一些代码在init函数中使用?

顺便说一句,我可以使用下面的代码而不是jQuery样式代码来创建相同的对象。我的代码& jQuery代码有什么不同?使用jQuery风格有什么好处吗?

myClass = window.myClass = function(x, y) 
{ 
    this.init(x, y); 
}; 

myClass.fn = myClass.prototype = 
{ 
    init: function(x, y) 
    { 
     this.x = x; 
     this.y = y; 
    } 
}; 

PS。我喜欢将初始逻辑分解为函数的编写代码,因为使用我的代码的其他人(如我的下面的代码)很容易覆盖此函数。

// override init function of myClass 
myClass.fn._old_init = myClass.fn.init; 
myClass.fn.init = function() 
{ 
    // logic for doing something before init 

    this._old_init(); 

    // logic for doing something after init 
}; 

感谢,

回答

0

jQuery对象初始化应该像下面的代码。

jQuery = window.jQuery = window.$ = function (x, y) 
{ 
    return new jQuery.fn.init(x, y); 
}; 

jQuery.fn = jQuery.prototype = 
{ 
    init: function() 
    { 
     // some logic for object initialization 
     return this; 
    } 
}; 

jQuery.fn.init.prototype = jQuery.fn; 

这段代码唯一的一个好处是它总是创建jQuery对象的实例,尽管您不使用new关键字来创建对象。

另一方面,如果您在调用初始化对象时不使用new关键字,那么使用初始化对象的init函数的代码不起作用。为了修复它,你必须添加一些代码,比如“J-P”示例来检查这个对象。如果它的类型不是当前类,它将自动为其创建实例。

这两个代码应该可以正常工作。但我喜欢jQuery风格而不是“J-P”风格,因为它很容易阅读和修改。

感谢,

2

这种方法应该很好地工作。你可能会错过的一件事是,使用这种技术,你不会创建一个myClass的实例;你将要创建一个myClass.prototype.init的实例。

因此,myClass.prototype中定义的任何方法都不适用于该实例。你要确保在init的原型点myClass的原型:

myClass.fn.init.prototype = myClass.fn; 

FWIW,我没有看到这种做法的任何实际的好处。这有什么问题? -

function myClass(x,y) { 

    if (!(this instanceof myClass)) { 
     return new myClass(x,y); 
    } 

    // Prepare instance 

} 

myClass.prototype = { /* Methods */ }; 

// It can still be overwritten: 

var oldMyClass = myClass; 

function myClass(x,y) { 

    // Hack some stuff here... 

    return new oldMyClass(x,y); 
} 
+0

,因为我刚刚发现,jQuery的使用这个语句(jQuery.fn.init.prototype = jQuery.fn)给了init函数jQuery的原型后实例你的回答是真实的。然而,你的回答和你的例子并没有解决我的问题,为什么jQuery使用这种风格来创建jQuery对象。 – 2009-12-07 07:37:15

+0

jQuery可能使用这种技术将构造函数与通用包装函数('jQuery()')分开。他们可以做到这一点,这可能是一个很早就在jQuery开发中做出的决定,并没有改变,因为它似乎有效地工作...... – James 2009-12-07 09:57:16

+0

@JP - 同意这可能是对早期决定的回忆 – 2009-12-07 17:54:13

0

我不能完全肯定的问题是什么,但我会尽我所能回答什么,我想你问。

new关键字用于实例化由功能原型上的init属性定义的函数返回的对象的新实例。

我相信代码是用这种方式,使得new关键字每次不要求你实例化一个新的jQuery 对象并委派对象的构造原型背后的逻辑。前者我相信是使库清洁器使用和后者保持初始化逻辑干净地在一个地方,并允许init递归调用构造并返回一个对象,正确匹配传递的参数。

您的第二个代码块不返回对象。在Firebug中试用它

var myClass1 = myClass(1,2); 
console.log(myClass1); 

你得到this.init is not a function错误。这将工作的唯一方法是,如果你使用new关键字在

var myClass1 = new myClass(1,2); 
console.log(myClass1); 

与此相比,在每种情况下类似于代码jQuery中

myClass = window.myClass = function(x, y) 
{ 
    return new myClass.fn.init(x, y); 
}; 

myClass.fn = myClass.prototype = 
{ 
    init: function(x, y) 
    { 
     this.x = x; 
     this.y = y; 
    } 
}; 

var myClass1 = myClass(1,2); 
console.log(myClass1); 

var myClass2 = new myClass(1,2); 
console.log(myClass2); 

,你正确地得到它返回一个对象x属性值为1,y属性值为2,是否使用new关键字。

+0

我只是在我的回答中告诉你。当您不使用新关键字时,我的问题中的代码不起作用。 – 2009-12-07 14:03:19

+1

从你的问题的措辞中不清楚这是你在说什么 – 2009-12-07 14:15:48

相关问题