30

我正在尝试直接在脑海中了解执行 jQuery 风格的函数链接的原则。我的意思是:

var e = f1('test').f2().f3();

我有一个例子可以工作,而另一个没有。我会在下面发布这些。我总是想学习一些东西是如何工作的首要原则,这样我就可以在它之上进行构建。到目前为止,我对链接的工作原理只有粗略和松散的了解,并且遇到了无法智能排除故障的错误。

我知道的:

  1. 函数必须返回自己,也就是“return this;”
  2. 可链接的函数必须驻留在父函数中,也就是在 jQuery 中,.css() 是 jQuery() 的子方法,因此 jQuery().css();
  3. 父函数应返回自身或自身的新实例。

这个例子有效:

var one = function(num){
    this.oldnum = num;

    this.add = function(){
        this.oldnum++;
        return this;
    }

    if(this instanceof one){
        return this.one;    
    }else{
        return new one(num);    
    }
}
var test = one(1).add().add();

但是这个没有:

var gmap = function(){

    this.add = function(){
        alert('add');

        return this;    
    }   

    if(this instanceof gmap) {
        return this.gmap;   
    } else{
        return new gmap();  
    }

}
var test = gmap.add();
4

5 回答 5

41

在 JavaScript 中,函数是第一类对象。当您定义一个函数时,它就是该函数对象的构造函数。换句话说:

var gmap = function() {
    this.add = function() {
        alert('add');
    return this;
    }

    this.del = function() {
       alert('delete');
       return this;
    }

    if (this instanceof gmap) {
        return this.gmap;
    } else {
        return new gmap();
    }
}
var test = new gmap();
test.add().del();

通过分配

新 gmap();
到变量 test 您现在已经构造了一个新对象,它“继承”了 gmap() 构造函数(类)的所有属性和方法。如果您运行上面的代码片段,您将看到“添加”和“删除”的警报。

在上面的示例中,“this”指的是窗口对象,除非您将函数包装在另一个函数或对象中。

Chaining 一开始对我来说很难理解,至少对我来说是这样,但是一旦我理解了它,我就意识到它是一个多么强大的工具。

于 2009-07-08T18:22:57.003 回答
4

可悲的是,直接答案必须是“不”。即使您可以覆盖现有方法(在许多 UA 中您可能可以,但我怀疑在 IE 中不能),您仍然会遇到讨厌的重命名:

HTMLElement.prototype.setAttribute = function(attr) { 
    HTMLElement.prototype.setAttribute(attr) //uh-oh;  
}

您可能逃脱的最好方法是使用不同的名称:

HTMLElement.prototype.setAttr = function(attr) {
    HTMLElement.prototype.setAttribute(attr);
    return this;
}
于 2012-06-10T01:43:36.377 回答
1

要“重写”一个函数,但仍然能够使用原始版本,您必须首先将原始函数分配给不同的变量。假设一个示例对象:

function MyObject() { };

MyObject.prototype.func1 = function(a, b) { };

要重写func1可链接性,请执行以下操作:

MyObject.prototype.std_func1 = MyObject.prototype.func1;
MyObject.prototype.func1 = function(a, b) {
    this.std_func1(a, b);
    return this;
};

这是一个工作示例。您只需要在您认为需要可链接性的所有标准对象上使用此技术。

当你完成所有这些工作时,你可能会意识到有更好的方法来完成你想要做的事情,比如使用已经内置可链接性的库。*cough* jQuery *cough*

于 2012-06-10T01:51:43.607 回答
0

首先,让我声明我正在用我自己的话来解释这一点。

方法链接几乎是调用另一个函数/方法返回的对象的方法。例如(使用 jquery):

$('#demo');

这个 jquery 函数选择并返回一个 id 为 demo 的 DOM 元素的 jquery 对象。如果元素是文本节点(元素),我们可以链接返回的对象的方法。例如:

$('#demo').text('Some Text');

因此,只要函数/方法返回一个对象,您就可以将返回对象的方法链接到原始语句。

至于为什么后者不起作用,请注意this使用关键字的位置和时间。这很可能是上下文问题。当您调用 时this,请确保它this指的是该函数对象本身,而不是窗口对象/全局范围。

希望有帮助。

于 2017-03-16T18:13:12.593 回答
-4

只需将该方法称为 var test = gmap().add();

因为 gmap 是一个函数而不是一个变量

于 2014-11-19T12:27:31.690 回答