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

发布于 2024-07-27 13:36:19 字数 996 浏览 11 评论 0原文

我试图在脑海中直接理解 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();

I'm trying to get the principles of doing jQuery-style function chaining straight in my head. By this I mean:

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

I have gotten one example to work, while another doesn't. I'll post those below. I always want to learn the first principle fundamentals of how something works so that I can build on top of it. Up to now, I've only had a cursory and loose understanding of how chaining works and I'm running into bugs that I can't troubleshoot intelligently.

What I know:

  1. Functions have to return themselves, aka "return this;"
  2. Chainable functions must reside in a parent function, aka in jQuery, .css() is a sub method of jQuery(), hence jQuery().css();
  3. The parent function should either return itself or a new instance of itself.

This example worked:

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();

But this one doesn't:

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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凉薄对峙 2024-08-03 13:36:19

在 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();

通过分配

new gmap();

to the variable test you have now constructed a new object that "inherits" all the properties and methods from the gmap() constructor (class). If you run the snippet above you will see an alert for "add" and "delete".

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

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

In JavaScript Functions are first class Objects. When you define a function, it is the constructor for that function object. In other words:

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();

By assigning the

new gmap();

to the variable test you have now constructed a new object that "inherits" all the properties and methods from the gmap() constructor (class). If you run the snippet above you will see an alert for "add" and "delete".

In your examples above, the "this" refers to the window object, unless you wrap the functions in another function or object.

Chaining is difficult for me to understand at first, at least it was for me, but once I understood it, I realized how powerful of a tool it can be.

凉月流沐 2024-08-03 13:36:19

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

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

最好的方法可能就是使用不同的名称:

HTMLElement.prototype.setAttr = function(attr) {
    HTMLElement.prototype.setAttribute(attr);
    return this;
}

Sadly, the direct answer has to be 'no'. Even if you can override the existing methods (which you probably can in many UAs, but I suspect cannot in IE), you'd still be stuck with nasty renames:

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

The best you could probably get away with is using a different name:

HTMLElement.prototype.setAttr = function(attr) {
    HTMLElement.prototype.setAttribute(attr);
    return this;
}
薔薇婲 2024-08-03 13:36:19

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

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 *咳嗽*

To "rewrite" a function, but still be able to use the original version, you must first assign the original function to a different variable. Assume an example object:

function MyObject() { };

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

To rewrite func1 for chainability, do this:

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

Here's a working example. You just need to employ this technique on all of the standard objects that you feel need chainability.

By the time you do all of this work, you might realize that there are better ways to accomplish what you're trying to do, like using a library that already has chainability built in. *cough* jQuery *cough*

阳光下慵懒的猫 2024-08-03 13:36:19

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

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

$('#demo');

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

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

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

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

希望有帮助。

First, let me state that i am explaining this in my own words.

Method chaining is pretty much calling a method of the object being returned by another function/method. for example (using jquery):

$('#demo');

this jquery function selects and returns a jquery object the DOM element with the id demo. if the element was a text node(element), we could chain on a method of the object that was returned. for example:

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

So, as long as a function/method returns an object, you can chain a method of the returned object to the original statement.

As for why the latter don't work, pay attention to where and when the keyword this is used. It is most likely a context issue. When you are calling this, make sure that this is referring to that function object itself, not the window object/global scope.

Hope that helps.

枕头说它不想醒 2024-08-03 13:36:19

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

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

Just call the method as var test = gmap().add();

as gmap is a function not a variable

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文