Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/435.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.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 找不到具有自定义原型函数的方法_Javascript_Jquery_Prototype - Fatal编程技术网

Javascript 找不到具有自定义原型函数的方法

Javascript 找不到具有自定义原型函数的方法,javascript,jquery,prototype,Javascript,Jquery,Prototype,我需要创建一个类似jQuery的定制原型,在使用了一些Google搜索词之后,我发现了一些代码: var myQuery, $; (function() { myQuery = $ = function(selector) { return new MyQuery(selector); }; var MyQuery = function(selector) { // Lets make a really simplistic selector implementation

我需要创建一个类似jQuery的定制原型,在使用了一些Google搜索词之后,我发现了一些代码:

var myQuery, $;

(function() {

myQuery = $ = function(selector) {
    return new MyQuery(selector);
};

var MyQuery = function(selector) {
    // Lets make a really simplistic selector implementation for demo purposes
    var nodes = document.getElementsByTagName(selector);
    for (var i = 0; i < nodes.length; i++) {
        this[i] = nodes[i];
    }
    this.length = nodes.length;
    return this;
};

// Expose the prototype object via myQuery.fn so methods can be added later
myQuery.fn = MyQuery.prototype = {
    // API Methods
    hide: function() {
        for (var i = 0; i < this.length; i++) {
            this[i].style.display = 'none';
        }
        return this;
    },
    remove: function() {
        for (var i = 0; i < this.length; i++) {
            this[i].parentNode.removeChild(this[i]);
        }
        return this;
    },
    hideAll: function(){
      alert("Hiding all.");  
    }
    // More methods here, each using 'return this', to enable chaining
};

}());
所有
标记都隐藏在页面上。但当我这么做的时候:

myQuery("p").hide();
myQuery.hideAll();
我得到一个错误: TypeError:myQuery.hideAll不是函数

我真的需要能够允许选择器有时,有时我不需要通过选择器发送

var divs = $('div');
divs.hide().remove(); // Or some other variation.

谢谢

hideAll是MyQuery对象的函数,而不是MyQuery

我想你应该试试 myQuery().hideAll()


myQuery()将返回一个myQuery对象

如果您希望myQuery.hideAll正常工作,这里有一个快速解决方案:

...
    },
    hideAll: function(){
        alert("Hiding all.");  
    }
    // More methods here, each using 'return this', to enable chaining
};
// you need this line so you can also access the functions without calling myQuery as a function
Object.assign(myQuery, MyQuery.prototype);
您现在不能调用myQuery.hideAll(),因为hideAll不是myQuery中的函数,而是myQuery.prototype中的函数(因此您需要一个myQuery实例,可以通过调用myQuery()获得该实例)

对象仅将MyQuery.prototype中字段的副本分配给MyQuery,这样您就可以在不需要实例的情况下访问它们


LE:这里有一个可行的方法:

根据您接受的初始答案,不要将整个原型作为静态方法分配给构造函数!您的原型方法仅用于“MyOuery”的实例

不要使用此行:

Object.assign(myQuery, MyQuery.prototype);
该行所做的是将所有原型方法作为静态方法重新分配到实际构造函数上。我的意思是,现在您可以这样做:

myQuery.hide() // That method should not be available at that level
// If you were to call that code right now, you would get this error:
// Uncaught TypeError: Cannot read property 'style' of undefined
hide()
方法应仅对MyQuery实例可用。无论何时使用查询选择器或标记调用构造函数,都可以创建MyQuery实例。换句话说:
$('div')
。但正如您所看到的,该方法在不应该的地方可用,并且在将来为您创建错误和潜在的bug

正确的方法是: 您需要在MyQuery构造函数本身上创建一个静态方法,而不是在原型上

以你的代码为例,我只做了一些修改

(function () {
    function MyQuery(selector) {
        if (!(this instanceof MyQuery)) {
            return new MyQuery(selector);
        }

        var nodes = document.querySelectorAll(selector);
        for (var i = 0; i < nodes.length; i++) {
            this[i] = nodes[i];
        }

        this.length = nodes.length;
    }

    // Create the static method here
    MyQuery.hideAll = function () {
        var all = document.querySelectorAll('*');
        for (var i = 0; i < all.length; i++) {
            all[i].style.display = 'none'
        }
    };

    MyQuery.fn = MyQuery.prototype = {
        hide: function () {
            for (var i = 0; i < this.length; i++) {
                this[i].style.display = 'none'
            }
            return this;
        },
        remove: function () {
            for (var i = 0; i < this.length; i++) {
                this[i].parentNode.removeChild(this[i]);
            }
            return this;
        }
    };

    window.myQuery = window.$ = MyQuery;
})();
同样,在本例中,原型上的方法用于需要使用的MyQuery实例。因此,只有在使用选择器实例化构造函数时,这些方法才可用

var divs = $('div');
divs.hide().remove(); // Or some other variation.

我希望这有助于您了解库的体系结构以及静态方法与原型方法之间的差异。

还有其他问题。您想要
myQuery.hideAll()
还是
myQuery(…).hideAll()
?后者已经起作用了,前者不需要原型。如果你想模拟jQuery,你应该看看像
$.parseJSON
这样的函数定义和像
.hide
这样的方法之间的区别。我不认为这是这里的问题…
myQuery
返回一个
myQuery
的新实例(参见OP代码顶部定义的
myQuery
),因此它确实包含
hideAll
。myQuery是一个返回myQuery对象的函数。myQuery对象包含hideAll函数。除非调用myQuery,否则它是无用的。这完全符合我的要求!!!谢谢tudy23!!你说这是一个“快速解决方案”,这不是正确的方法吗?@Rizo,这是正确的方法。我所说的快速解决方案是指我在解释之前给出了解决方案。很抱歉让你怀疑。没问题,你用这个节省了我很多时间!真的很感谢!哇,KevBot,这太棒了!我唯一的错误是打字错误:for每个都不是一个函数,我用for()替换了它它工作得很好。非常感谢!修复了。这个错误并没有出现在我设计的Chrome中,但在Firefox和Safari中出现了。所以,为了确保其他人不会感到困惑,我对它进行了修改,使用了一些
for
循环以及您开始使用的那些循环。