Javascript requireJS对象原型只能是对象或null-jQuery
我在使用requireJS时遇到问题。我试图将jQuery与其他脚本一起加载,但出现了一个错误。代码如下: index.htmlJavascript requireJS对象原型只能是对象或null-jQuery,javascript,jquery,object,requirejs,Javascript,Jquery,Object,Requirejs,我在使用requireJS时遇到问题。我试图将jQuery与其他脚本一起加载,但出现了一个错误。代码如下: index.html <!DOCTYPE html> <html lang="en"> <head></head> <body> <script data-main="./app" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<script data-main="./app" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.min.js"> </script>
</body>
</html>
main.js
(function(){
'use strict';
require.config({
paths: {
jQuery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min',
helpers: 'helpers',
},
shim: {
jQuery: {
exports: '$'
}
}
});
requirejs(['main']);
})();
define(function(require){
require(['jQuery', 'helpers'], function($){
$('body').css({'background': 'red'});
});
});
define(function(){
'use strict';
Object.prototype.extend = function(parentClass){
if(!Object.create){
Object.prototype.create = function(proto){
function F(){}
F.prototype = proto;
return new F();
};
}
this.prototype = Object.create(parentClass.prototype);
this.prototype.constructor = this;
}
});
helpers.js
(function(){
'use strict';
require.config({
paths: {
jQuery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min',
helpers: 'helpers',
},
shim: {
jQuery: {
exports: '$'
}
}
});
requirejs(['main']);
})();
define(function(require){
require(['jQuery', 'helpers'], function($){
$('body').css({'background': 'red'});
});
});
define(function(){
'use strict';
Object.prototype.extend = function(parentClass){
if(!Object.create){
Object.prototype.create = function(proto){
function F(){}
F.prototype = proto;
return new F();
};
}
this.prototype = Object.create(parentClass.prototype);
this.prototype.constructor = this;
}
});
我得到以下错误:
未捕获类型错误:对象原型只能是对象或null:未定义
在helpers.js的第12行,一旦需要jQuery,它就会激发所有Object.prototype属性。因为:
define(function(){
'use strict';
Object.prototype.extend = function(parentClass){
alert('This code shoud be executed only when called on objects!');
if(!Object.create){
Object.prototype.create = function(proto){
function F(){}
F.prototype = proto;
return new F();
};
}
this.prototype = Object.create(parentClass.prototype); //The error occurs here because the code in the scope is executed and parentClass is undefined
this.prototype.constructor = this;
}
});
在extend方法中提醒消息。为什么?如果没有使用requireJS,jQuery可以很好地与我的脚本配合使用。有什么帮助吗
文件结构:
测试文件夹
- index.html
- app.js
- helpers.js
- main.js
对象。prototype
。您遇到的问题只是它可能导致的许多问题之一解决问题的正确方法是使用另一种方法,而不是将extend
添加到Object.prototype
为什么它不起作用?当您执行Object.prototype.extend=function(){…
时,您正在Object.prototype
上声明一个新属性,默认情况下,此属性是可枚举的。这意味着,在该赋值生效后,如果您执行for(var i in{})console.log(i)
您将在控制台上获得extend
现在,jQuery有一个很好的函数名为。有趣的是,当jQuery初始化时,它使用jQuery.extend
来扩展自身。如果您查看jQuery源代码,您会看到如下内容:
jQuery.extend( {
expando: ...,
isReady: ...,
});
当只使用一个参数调用extend
时,这意味着要扩展的东西是this
,这就是jQuery
本身。因此extend
将传递给它的对象作为参数,并在循环中使用for…迭代其属性。在它运行到ex之前,这一切都很好倾向于添加到Object.prototype
中的。当它到达此属性时,它会用Object.prototype
中的方法覆盖自己的extend
方法。因此下次运行jQuery.extend
时,它会运行您分配给Object.prototype.extend
的代码,您会得到错误
您还应该将jQuery模块称为jQuery
而不是jQuery
,并删除它的shim
配置。jQuery调用define
(因此它没有shim
),并将其名称硬编码为jQuery
。有关详细信息,请参阅
以下内容仅用于说明。请勿在生产代码中使用。
如果用以下代码替换helpers.js
,则问题将消失:
define(function() {
'use strict';
Object.defineProperty(Object.prototype, "extend", {
value: function(parentClass) {
if (!Object.create) {
Object.defineProperty(Object.prototype, "create", {
value: function(proto) {
function F() {}
F.prototype = proto;
return new F();
},
enumerable: false,
writable: true
});
}
this.prototype = Object.create(parentClass.prototype);
this.prototype.constructor = this;
},
enumerable: false,
writable: true
});
});
这用于将extend
定义为不可枚举属性,这样它就不会在中显示在中,也可以写入,这使得jQuery可以定义自己的jQuery.extend
。对于create
也可以这样做。我发现,将方法直接附加到对象不是一个好的做法。因此或者,我创建了自己的库,如:
define(function(){
var _ = (function(){
'use strict';
function _(o){
if(!(this instanceof _)){
return new _(o);
}
this.o = o;
}
_.isArray = function(arg){
return Object.prototype.toString.call(arg) === '[object Array]';
};
_.prototype = {
extend: function(parentClass){
if(!Object.create){
Object.prototype.create = function(proto){
function F(){}
F.prototype = proto;
return new F();
}
}
this.o.prototype = Object.create(parentClass.prototype);
this.o.prototype.constructor = this;
}
// Other methods here
};
return _;
})();
return _;
});
然后像这样使用:
var MyClass = (function(){ ... })();
var MyOtherClass = (function(){
_(MyOtherClass).extend(MyClass);
function MyOtherClass(){
//constructor
}
return MyOtherClass;
})();
并且没有更多错误:)您能在调用堆栈中看到调用extend
的位置吗?它是否在某个地方被调用而没有参数?extend
不会在任何地方被调用。您可以创建与示例中相同的文件,并且在不调用extend
方法的情况下将面临相同的问题。我已经尝试了Object.prototype.asdfh
然后再次调用该方法。所有的Object.prototype.method\u NAME
在初始化时都会被自动调用。你是说它不会被调用,也会被自动调用。这是什么?@Mathletics我说在我的应用程序中没有一个地方我不会调用extend
方法。在初始化本身上,它被自动调用,这是实际的问题。@Mathletics我的意思是我没有调用extend
函数。我编写它是为了将来需要扩展我的类。jQuery以某种方式立即调用它自己,行require(['jQuery',helpers'),function($){
已到达。如果我仅使用require(['helpers',function(){..}
然后extend
方法没有被激发,因为它还没有在任何地方被调用。它有意义吗?很高兴提供帮助。我编辑了我的答案,添加了一个关于jQuery模块名称的注释,并且没有必要添加垫片。我建议查看,看看我对答案所做的更改。