如何设置接收器

Posted

技术标签:

【中文标题】如何设置接收器【英文标题】:How to set the receiver 【发布时间】:2012-02-24 16:15:29 【问题描述】:

如何重写以下形式的函数:

 foo = function(arg1,arg2)....;

转换成arg1 成为接收者的形式,像下面这样使用?

arg1.foo(arg2);


编辑 我发现使用 jQuery,我可以做到这一点。
jQuery.fn.foo = function(arg)
  ...

javascript 不使用 jQuery 的方法是什么?

【问题讨论】:

函数foo 必须在arg1 对象中。意思是arg1 需要是你的类的一个实例,它包含foo 函数。 对于未来的人(就像我一样,直到我成为过去的苦工),知道arg1DOMElement 的要求可能很有用... 【参考方案1】:

jQuery 返回的对象是 jQuery 对象,而不是 DOM 对象。它们包含 DOM 对象的集合,但 jQuery 根本不直接向 DOM 对象添加任何方法。 jQuery.fn 只是对 jQuery 返回的对象的原型的引用,允许您直接向该原型添加方法。

既然您对重现 jQuery 的行为感兴趣,您也可以这样做:将原生 DOM 对象包装在您自己的类中,向该包装类添加您想要的任何方法。请注意,您不能只在 jQuery 实例上调用任何 DOM 对象方法; jQuery 定义了一些用于调用实际 DOM 方法的实用方法,但是为了调用许多其他 DOM 方法,您需要访问包装在 jQuery 实例中的真实 DOM 对象。您的自定义包装器类也有同样的限制——您需要在包装器上实现将调用转发到底层 DOM 对象的方法。

例子:

function DOMWrapper(domObject) 
    this.domObject = domObject;


DOMWrapper.prototype = 

    constructor: DOMWrapper,

    foo: function(arg1, arg2, arg3) 
        // this.domObject refers to the wrapped object here
        this.domObject.nativeMethod();
        // you could do things like this here:
        return this.bar.call(this.domObject, arg1, arg2, arg3);
    ,

    bar: function(arg1, arg2, arg3) 
        // now, even though "bar" is defined as a method of
        // the DOMWrapper prototype, it has been invoked by "foo"
        // in the context of the wrapped DOM object, so
        // "this" refers directly to the DOM object in this method

        // this goes to the actual DOM nativeMethod:
        return this.nativeMethod();
    ,

    domMethodWrapper: function() 
        return this.domObject.nativeMethod();
    


【讨论】:

【参考方案2】:

解决方案 1

直接为每个元素附加一个函数。 (更兼容)

演示:http://jsfiddle.net/SO_AMK/tE6gf/

jsFiddle 今天的 slow 所以这里是JS Bin mirror

JavaScript:

var elm = document.getElementById("elm");

elm.foo = function(arg) 
    alert(arg.arg1); // What I thought you might've meant :D
;

elm.foo(
    arg1: "Arg 1 Value",
    arg2: "Arg 2 Value",
    arg3: "Arg 3 Value",
    arg4: "Arg 5 Value"
);

var arg1 = document.getElementById("div2");

// To match your example
arg1.foo = function(arg1, arg2) alert(arg1); ;

var arg2 = "This is a random string";

arg1.foo(arg2);

解决方案 2

扩展Element.prototype。 (仅向后兼容 IE 7)

演示:http://jsfiddle.net/SO_AMK/8W2Nx/

JavaScript:

Element.prototype.foo = function(arg1, arg2) 
    alert(arg1);
;

document.getElementById("test").foo("String 1");​

【讨论】:

为了做到这一点,每次创建 dom 对象时都必须在对象上定义函数。 我不确定我是否理解这个问题,您想为 all 元素创建类似 jQuery 的语法而不创建库或启动一个库吗? 你可以通过this 的方式做到这一点,但我不知道修改页面上的每个元素会产生什么后果。 上面的脚本非常快,正如你在this 演示中看到的那样,扩展1000个元素大约需要5ms。 @sawa 我刚刚添加了另一个解决方案。【参考方案3】:

这样的?

var arg1 =  
    foo: function(arg2)   
;

arg1.foo(arg2)

更新

您应该能够将函数添加到对象上:

var test = document.getElementById('test');

test.foo = function(arg) 
    alert(this.innerhtml + " : " + arg);
;

test.foo("Hello");

http://jsfiddle.net/sJSDS/

【讨论】:

我已经有一个 DOM 对象arg1,不能将其更改为其他对象。如何为所有 DOM 对象定义它? @sawa 你从哪里得到对象? @sawa 我认为并非所有浏览器都支持扩展 DOM 原型(how Prototype does it、DOM prototype in Mozilla、before IE8 you can't access it for sure) @RichardD 我通过document.getElementById()得到它。【参考方案4】:

定义你要使用的函数:

function original_foo(color) 
    this.style.backgroundColor = color;

然后遍历所有 dom 节点并将函数作为方法附加:

var all_nodes = document.querySelectorAll("*");
for (var i in all_nodes) 
    var node = all_nodes[i];
    node.foo = original_foo;

现在调用方法:

var d = document.getElementById("d2");
d.foo("red");

document.getElementById("d1").foo("green");

看到这个jsfiddle: http://jsfiddle.net/bjelline/G9e9C/

【讨论】:

【参考方案5】:

你可以这样解决:

function foo(arg1, arg2) 
   if (typeof arg1 == 'function')
      arg1(arg2); // or 'return arg1(arg2)' if necessary
   else
      return false;

您可以通过以下方式轻松测试它:

foo(alert,'hello world');

【讨论】:

以上是关于如何设置接收器的主要内容,如果未能解决你的问题,请参考以下文章

如何设置接收器

HAL库如何设置SPI2一直使能接收中断

DotPulsar:如何设置消费者接收队列大小?

如何设置Netty的接收Buffer为堆内存模式

S3 接收器连接器的配置设置

手机接收电子邮件如何设置?