主干和RequireJS冲突-实例或构造函数
Backbone and RequireJS conflicts - instances or constructors?
有人能解释一下之间的根本区别吗
define(['backbone'], function(Backbone) {
MyModel = Backbone.Model.extend({
});
});
define(['backbone', 'models/mymodel'], function(Backbone){
var app = Backbone.View.extend({
initialize: function() {
var model = new MyModel();
}
});
});
和:
define(['backbone'], function(Backbone) {
var MyModel = Backbone.Model.extend({
});
return MyModel;
});
define(['backbone', 'models/mymodel'], function(Backbone, MyModel){
var app = Backbone.View.extend({
initialize: function() {
var model = new MyModel();
}
});
});
在前者中,第一个模块简单地定义了MyModel。在后者中,它被创建为一个变量并返回,第二个模块需要在导入时将其放入参数中。
我看到的RequireJS示例似乎在两者之间有所不同,但我并不真正理解其中的区别——一个返回实例,另一个返回构造函数吗?
在我的应用程序中,我甚至没有注意到我实际上在不同的地方使用了这两种方式,我认为这会造成问题。我用了很多
self = this
self.model.doSomething
在我的视图和模型中,随着我的应用程序越来越大,我开始出现错误,因为与自我的定义存在冲突。
短版本:第一个版本==错误。
中等版本:第一个版本通过使用全局变量完全绕过Require,而第二个版本实际上使用Require。
长版本:
主干模块的工作方式是运行"define",向它传递一个函数(通常还有一组依赖项),从该函数返回的任何内容都被定义为该模块。所以如果我这样做:
// Inside foo.js
define([], function() {
return 1;
});
我已经将"foo"模块定义为1
,所以如果在其他地方我这样做:
define(['foo'], function(foo) {
alert(foo); // alerts 1
});
您的第一个版本没有返回任何内容,因此实际上根本没有创建Require模块。
那么它是如何工作的呢?好吧,在那个版本中你会这样做:
MyModel = Backbone.Model.extend({
非:
var MyModel = Backbone.Model.extend({
所以这和做是一样的
window.MyModel = Backbone.Model.extend({
然后,当代码的第二部分运行时,它访问window.MyModel
,并工作。。。但它在这个过程中完全绕过了Require.js。
我认为最重要的一点是:始终声明(即var
)您的Java脚本变量。我不同意克罗克福德说的每一句话,但他在这一点上完全正确。如果你不养成这个习惯,你会遇到很多错误(有Require和没有Require)。
除此之外,接下来最重要的事情可能是:始终返回传递给define
的函数中的某些内容。在某些特殊情况下,您不想返回任何内容,但除非您有意解决其中一种情况,否则您应该始终返回一些内容来定义模块。
最后,如果您使用Require,代码中的每个变量都应该:
- 来自
define
函数(即,它应该是传递给定义的函数中的参数变量),或者 - 它应该在该文件中声明(即
var
-ed)
如果您使用JSLint或'use strict';
(正如Valentin Nemcev建议的那样),或者如果您使用Eclipse之类的编辑器,您的工具可以帮助您确保这一点(事实上,也可以使其易于确保)。
MyModel = Backbone.Model.extend({});
在这里,您不是返回构造函数,而是定义一个全局变量,然后在不同的模块中访问它。
事实上,这是错误的,它是偶然发生的。您应该从define
中return
您的模块,并通过其他模块中的参数访问它们。
像这样:
return Backbone.Model.extend({});
您应该使用严格模式来避免JS中的全局变量出现问题。
此外,JS中的构造函数只是一个要使用new
运行的函数。Backbone extend
总是返回一个构造函数,您可以通过使用new
调用构造函数来创建一个模型实例,就像您在两个示例中所做的那样。
- ES6构造函数返回基类的实例
- 我应该在原型上还是在新创建的实例上调用构造函数方法
- 为什么实例构造函数指向最上面的函数构造函数对象
- 主干和RequireJS冲突-实例或构造函数
- 在定义了构造函数之后,是否可以将实例属性添加到JavaScript原型中
- 销毁构造函数实例
- 在nodejs中,如何使模块的单个实例具有不同参数的构造函数
- 构造函数的“实例”是否有严格的定义
- 只为构造函数的所有实例触发一次事件侦听器
- 如何实例化其构造函数使用 yield 的对象
- 在实例化期间使用构造函数变量
- 为什么更改函数的 .prototype 会影响已使用该构造函数创建的对象的“实例”
- 如何在使用构造函数进行原型设计时访问实例
- 何时有时将对象类型定义为将实例绑定方法镜像为构造函数上的静态实用程序函数很有用
- 通过构造函数属性和运算符实例设置继承
- 如何在javascript中使用构造函数返回实例或sthelse
- 是否可以在没有构造函数参数的情况下实例化空对象/对象
- 函数是否无法返回构造函数并创建新实例
- 如何使用新构造函数为 json 中的每个节点创建实例
- 构造函数中的私有函数声明是否在每次创建实例时重新实例化