Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/445.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript requireJS对象原型只能是对象或null-jQuery_Javascript_Jquery_Object_Requirejs - Fatal编程技术网

Javascript requireJS对象原型只能是对象或null-jQuery

Javascript 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

我在使用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.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模块名称的注释,并且没有必要添加垫片。我建议查看,看看我对答案所做的更改。