基本的对象/函数链在 javascript 中是如何工作的?

IT技术 javascript methods chaining method-chaining
2021-02-08 20:20:32

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

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

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

我知道的:

  1. 函数必须返回自己,也就是“返回这个;”
  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();
5个回答

在 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”指的是 window 对象,除非您将函数包装在另一个函数或对象中。

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

我认为你可以删除if ... else ...,这对我来说没有多大意义。构造函数this默认返回,也可以显式返回。我相信this.gmap会是未定义的,并且new gmap()会使构造函数永远循环,所以我不知道为什么这适用于 OP。
2021-03-25 20:20:32

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

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

最好的办法是使用不同的名称:

HTMLElement.prototype.setAttr = function(attr) {
    HTMLElement.prototype.setAttribute(attr);
    return this;
}
请注意这个答案是针对另一个问题的
2021-03-21 20:20:32
看起来我会坚持使用 jQuery 进行链接!
2021-04-10 20:20:32

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

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*

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

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

$('#demo');

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

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

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

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

希望有帮助。

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

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

这将不起作用,因为add未在 上定义gmap(),而仅在 上定义new gmap()
2021-03-28 20:20:32