如何将参数传递给匿名Javascript函数?

时间:2009-12-16 00:34:46

标签: javascript anonymous-function lambda

我正在写一个简单的计数器,我想让用户安装这个计数器非常简单。我见过的最简单的计数器代码之一(适用于安装它的用户)是Google Analytics代码

所以我想将主代码存储在一个文件中,安装我的计数器的用户只需要像这样设置websiteID:

<html><head><title></title></head><body>
<script type="text/javascript" src="http://counterhost.lan/tm.js">
var websiteId = 'XXXXX';
</script>
</body></html>

这是我的代码:

<script type="text/javascript" src="http://counterhost.lan/tm.js">
var page = _gat.init('new');
</script>

这是我的JS文件:

(function() {
    var z = '_gat';
    var aa = function init(data) { alert(data); alert(z);};

    function na() {
        return new z.aa();
    }
    na();
})();

我尝试了解Google Analytics javascript代码,但我没有这样做。任何人都可以建议如何在标签之间指定变量,然后在匿名函数中读取它,该函数位于javascript文件中? 感谢。

6 个答案:

答案 0 :(得分:2)

在您的示例中,websiteId是一个全局变量。因此除非存在具有相同名称的局部变量

,否则它可以在任何地方访问,包括匿名函数
<script> var websiteId = "something"; </script>

稍后在页面中或包含js文件...

(function() {
    alert(websiteId); //this should work
})();

答案 1 :(得分:2)

您可以将变量传递给匿名函数,如下所示:

(function(arg1, arg2, arg3) {
    alert(arg1);
    alert(arg2);
    alert(arg3);
})("let's", "go", "redsox");

// will alert "let's", then "go", then "redsox" :)

答案 2 :(得分:1)

  

任何人都可以建议我如何在标签之间指定变量然后阅读它[...]

如果您的标签同时具有SRC属性和JS内容,则不会。

<script type="text/javascript" src="http:/x.com/x.js"></script>

..不同于,

<script type="text/javascript">
    var x = 1;
</script>

可选择将JS变量添加到SCRIPT标记的一个框架是Dojo。因此,如果您正在使用Dojo,则可以通过编写将变量添加到全局 djConfig 哈希中,

<script type="text/javascript" src="mxclientsystem/dojo/dojo.js"
    djConfig="
    usePlainJson: true,
    parseOnLoad: true
">
</script>

Dojo通过运行SCRIPT标记并评估自定义 djConfig 属性来实现此目的。

然而,这并不能解决您的问题。

你真的想要两个SCRIPT标签。有人说,

<script type="text/javascript">
    var websiteId = '123456';
</script>

将设置全局变量 websiteId 和第二个

<script type="text/javascript" src="http:/x.com/myreporter.js"></script>

可以从任何地方加载并读出 websiteId 变量,并且我假设将其报告回来。

答案 3 :(得分:0)

我并不完全清楚你在问什么,但是......

您可以使用id属性标记任何HTML元素,然后使用
document.getEntityById()检索该特定元素。

您还可以为任何HTML元素提供具有您自己选择名称的用户定义属性,然后在Javascript中为该元素获取和设置它们。

答案 4 :(得分:0)

我认为你对JS对象的调用方式有点困惑。

z是一个字符串,'_gat'。您无法在其上调用aa(),因为String中没有名为aa的成员。 aa是存储在局部变量中的独立函数。即使您确实调用了aa(),它也不会返回任何内容,因此在其结果中使用new运算符是没有意义的。 new只能在构造函数上调用。

我猜你的意思是:

var _gat= function() {

    // Private variable
    //
    var data= null;

    // Object to put in window._gat
    //
    return {

        // Set the private variable 
        //
        init: function(d) {
            data= d;
        }
    };
}();

然后在第二个示例中调用_gat.init('foo')会将变量设置为网站ID 'foo'。这是有效的,因为_gat对象是匿名函数内定义的返回{init: function() {...}}对象,在隐藏的data变量上保留引用('闭包')。

答案 5 :(得分:0)

如果您将src属性指定为script元素的一部分,则script元素标记内的任何代码都不会被执行。但是,您可以使用以下代码添加此功能。我从Crockford得到了这个技术(我相信是他),他在谈论无关的渲染性能主题和异步将脚本加载到页面中时使用它。

JavaScript的:

(function() {
    // Using inner class example from bobince's answer
 var _gat = (function() {
     var data= null;

     return {
         init: function(d) {
          console.info("Configuration data: ", d);
             data = d;
         }
     }
 })();

 // Method 1: Extract configuration by ID (SEE FOOT NOTE)
 var config = document.getElementById("my-counter-apps-unique-and-long-to-avoid-collision-id").innerHTML;

 // Method 2: search all script tags for the script with the expected name
 var scripts = document.getElementsByTagName("script");

 for ( var i=0, l=scripts.length; i<l; ++i ) {
  if ( scripts[i].src = "some-script.js" ) {
   config = scripts[i].innerHTML;
   break;
  }
 }

 _gat.init( eval("(" +config+ ")") );
})();

HTML:

<script type="text/javascript" src="some-script.js" id="my-counter-apps-unique-and-long-to-avoid-collision-id">
 {some: "foo", config: "bar", settings: 123}
</script>

两种方法都有缺点:

  1. 使用唯一且无冲突的ID可以更准确,更快地确定正确的脚本元素;但是,这不是有效的HTML4 / XHTML标记。在HTML5中,您可以定义任意属性,因此当时不会出现问题

  2. 此方法是有效的HTML标记;但是,如果您的网址可能会发生变化(例如:http vs https),我所展示的简单比较很容易被破坏,并且可能会有更强大的比较方法

  3. 关于eval

    的说明

    这两种方法都使用eval。关于这个特征的典型口头禅是“eval是邪恶的”。但是,这就是说,在不知道eval 的危险的情况下使用eval 是邪恶的。

    在这种情况下,AFAIK,script标签中包含的数据不会受到注入攻击,因为在解析HTML时,一旦到达该元素,就会执行eval'ing脚本(显示的代码)进入DOM。之前可能已定义的脚本无法访问计数器script标记中包含的数据,因为DOM树中的节点在执行时不存在。

    可能是这样的情况:从先前包含的脚本执行的定时setTimeout可能能够在计数器的script包含和eval的时间之间运行;但是,这可能是也可能不是这种情况,如果可能的话,可能不会如此一致,具体取决于CPU负载等。

    故事的道德,如果你担心它,请包含一个非eval的JSON解析器并改为使用它。