【问题标题】:What do you call this JavaScript syntax, so I can research it?你把这个 JavaScript 语法叫做什么,所以我可以研究一下?
【发布时间】:2011-03-13 14:26:51
【问题描述】:

1) 在以下代码中,将gameOfLive 设为变量而不仅仅是function gameOfLife() 的原因是什么?

2) 什么是gol?它看起来像一个数组,但我不熟悉它的语法或它的名称。

我正在学习http://sixfoottallrabbit.co.uk/gameoflife/

if (!window.gameOfLife) var gameOfLife = function() {

    var gol = {
        body: null,
        canvas: null,
        context: null,
        grids: [],
        mouseDown: false,
        interval: null,
        control: null,
        moving: -1,
        clickToGive: -1,
        table: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(''),
        tableBack: null,

        init: function(width, height) {
            gol.body = document.getElementsByTagName('body')[0];
            gol.canvas = document.createElement('canvas');
            if (gol.canvas.getContext) {
                gol.context = gol.canvas.getContext('2d');
                document.getElementById('content').appendChild(gol.canvas);
                gol.canvas.width = width;
                gol.canvas.height = height;
                gol.canvas.style.marginLeft = "8px";

                gol.control = document.getElementById('gridcontrol');

                gol.canvas.onmousedown = gol.onMouseDown;
                gol.canvas.onmousemove = gol.onMouseMove;
                gol.canvas.onmouseup = gol.onMouseUp;

                gol.addGrid(48,32,100,44,8);

                gol.refreshAll();
                gol.refreshGridSelect(-1);
                gol.getOptions(-1);

                gol.genTableBack();
            } else {
                alert("Canvas not supported by your browser. Why don't you try Firefox or Chrome? For now, you can have a hug. *hug*");
            }
        },
    }
}

【问题讨论】:

  • 你好。我是你正在研究的 JS 的作者。首先我要道歉。这是一个巨大的混乱。没有评论,成吨的匆忙,被黑的代码。然而,我正在开发一个更整洁的版本。很多人已经回答了您关于代码的问题,我希望他们有所帮助。完成后,我一定会提醒您注意更整洁的版本。但享受研究我造成的混乱。 xD
  • 我非常喜欢它! :-) 请让我知道“更整洁”的版本何时发布。我能够修改“规则”以考虑颜色,并根据包括它们在内的规则进行填充。很有趣!

标签: javascript conways-game-of-life


【解决方案1】:
var gameOfLife = function() { }

是一个函数表达式,而

function gameOfLife() { }

是一个函数声明。

引用 Juriy ‘kangax’ Zaytsev 关于Function expressions vs. Function declarations:

有细微的差别 声明的行为和 表达式。

首先,函数声明 在任何之前被解析和评估 其他表达式是。即使 声明位于最后一个 来源,它将被评估 首先是作用域中包含的任何其他表达式。 […]

另一个 重要功能性状 声明就是声明它们 有条件地是非标准化的并且 因环境而异。 你永远不应该依赖函数 有条件地声明并使用 而是函数表达式。

在这种情况下,正如 Joel Coehoorn 在评论中提到的那样,gameOfLife 是有条件定义的,因此需要使用函数表达式。

这些条件定义函数的一般用例是增强浏览器中的 JavaScript 功能,这些浏览器不支持较新的函数(在以前的 ECMAScript/JavaScript 版本中不可用)。您不想使用函数声明来执行此操作,因为无论如何它们都会覆盖本机功能,这很可能不是您想要的(考虑到速度等)。一个简短的example:

if (!Array.prototype.indexOf) { 
    Array.prototype.indexOf = function(item, from) {
        /* implement Array.indexOf functionality,
           but only if there's no native support */
    }
}

函数表达式的一个主要缺点是您实际上将匿名函数分配给变量。这可以生成debugging harder,因为当脚本执行停止时(例如,在您设置的断点上),函数名称通常是未知的。一些 JavaScript 调试器,比如 Firebug,会尝试给出分配给函数的变量的名称,但是由于调试器必须通过动态解析脚本内容来猜测这一点,这可能太难了(这会导致(?)() 被显示,而不是函数名)甚至是错误的。

(例如,在页面上阅读,虽然它的内容并不完全适合初学者)

【讨论】:

  • +1。在这种情况下,函数是有条件声明的 (if (!window.gameOfLife)),因此他们需要首选表达式。
  • 那个条件声明的意义何在?我真的看不出添加 if 语句有什么好处。如果你只是使用一个普通的函数声明,它不会只声明一次吗?
  • @Lèse:如果您想提供一些并非所有(每个版本)浏览器都可用的功能,您可以使用if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, from) { … }; 之类的东西,请参阅code.google.com/p/oz-js/source/browse/trunk/oz.js#234。使用函数声明,您总是会覆盖本机函数,这在大多数情况下是首选。
  • 是的,这种用法是有道理的。但是在这种情况下,不只是检查gameOfLife() 是否已声明吗?我查看了 .js 文件,不清楚如何在脚本运行时已经声明了 gameOfLife()。
  • @Lèse:我想这更像是一般的健全性检查。我现在已经厌倦了研究这个具体案例,但我可以想象脚本可以以某种方式多次插入的案例;你不想因为用最初的值覆盖它们而丢失你的值。
【解决方案2】:
  1. 在 JavaScript 中,函数是 first class objects。您可以将它们存储在对象(变量)中并将它们作为参数传递给函数。每个函数实际上都是一个Function 对象。

  2. gol 是一个对象,正在使用object literal 表示法进行初始化。

【讨论】:

  • 使用变量语法的一大原因实际上是为了提醒自己(或其他程序员)gameOfLife 实际上是一个变量。它可以像其他任何东西一样被更改和覆盖。只是它当前拥有一个功能。语法“var gameOfLife = function...”是一个视觉提示。
  • @Ryan:这没有回答为什么使用函数表达式而不是函数声明的问题。使用var 的另一个原因是将gol 定义在gameOfLife 的范围内。
  • 作为代码的作者,我想补充一些信息:我声明 gameOfLife 本质上是一个命名空间,用于包含我的应用程序所包含的所有其他内容。如果你向下滚动到它的底部,你会看到 gameOfLife() “函数”以“return gol;”结尾。然后在最后的“}”之后有“()”。所以我正在执行函数并将返回值存储在 gameOfLife 中。它返回什么?它返回 gol 对象。所以 gameOfLife 就成了 gol 的代名词。 gameOfLife 是在命名空间外使用的好名字,而 gol 是在命名空间内使用的简称。
【解决方案3】:

1) 在以下代码中,将 gameOfLive 设为变量而不仅仅是“函数 gameOfLife()”的原因是什么?


在全局级别定义的变量是窗口对象的成员。因此,通过将其设为变量,您可以使用语法window.gameOfLife()。这也是他们可以在您的 sn-p 开头使用if (!window.gameOfLife) 检查的原因。

但这并不能真正解释为什么他们选择这样做,而函数声明会做同样的事情。 Marcel Korpel's answer 更好地解释了这两个选项的“原因”。


2) 什么是黄金?它看起来像一个数组,但我不熟悉语法或它的名称。


这种语法称为紧凑对象表示法。有趣的是,“紧凑”对象是在函数内部声明的。在这样的函数中声明对象很有用,因为您可以使用它来构建具有(有效)私有成员的 javascript 对象。

关键是要记住javascript中的函数和对象是一回事。因此,完整的gameOfLife() 函数实际上是一个对象定义。此外,声明为gameOfLife 成员的gol 对象很可能是定义私有成员的常用技术的一部分。 gameOfLife() 函数/对象将返回此 gol 对象。在gameOfLife() 函数/对象中声明的所有其他项实际上成为返回的gol 实例的私有成员,而在gol 对象本身中声明的所有内容都是公共的。他们真正想做的是最终写出这样的代码:

var game = new gameOfLife();

现在,当他们这样做时,游戏变量将保存一个gol 对象。这个对象中的方法仍然可以访问在完整的gameOfLife() 函数中声明的项目,但是其他代码没有(至少,不那么容易)。因此,这些项目实际上是私有的。 gol 对象本身中的项目仍然是公开的。因此,您拥有一个包含私有和公共成员的对象,用于正确封装/信息隐藏,就像您使用其他面向对象的语言构建一样。


【讨论】:

  • @Marcel - 请参阅我的答案第一部分的倒数第二句。
  • 是的,对不起,你是对的,你也说过“函数声明会做同样的事情”。我现在要睡一会儿……;-)
  • @Marcel - 公平地说,这句话是在我读完你的答案后编辑的,回头看看原来的问题,因为我回答错了,所以不得不拍我的头。我不知何故以为他在问该对象如何用作窗口对象的成员。
【解决方案4】:

将函数放入变量中可以让您稍后再用另一个函数替换它,从而将函数透明地替换为代码的其余部分。这与您在表单小部件上指定“onClick=”时所做的相同。

【讨论】:

    【解决方案5】:

    根据this page,以他们的方式声明gameOfLife 与以您的方式声明它没有什么不同。他们定义gol 的方式使其成为对象(或者您可以将其视为关联数组)。数组的类似快捷方式是使用方括号而不是花括号。

    【讨论】:

    • 不完全正确:数组是一种对象,但不能像您暗示的那样使用花括号定义数组。函数表达式(如示例中)和函数声明(如 OP 所希望的那样)之间存在重大差异:“函数声明在任何其他表达式之前被解析和评估。 […] 函数声明的另一个重要特征是,有条件地声明它们是非标准化的,并且在不同的环境中有所不同。你永远不应该依赖于有条件地声明函数,而应该使用函数表达式。”
    • 我从未说过可以使用花括号定义数组,只是我发现比较 JavaScript 对象和关联数组很有用。谢谢你的链接。我想这两个函数定义之间存在一些差异,尽管找不到来源。实际上,根据我的经验,很容易知道什么时候使用什么,而且通常没什么区别。
    【解决方案6】:

    当然:解释语法:

    函数是 javascript 中的第一类对象,因此您可以将函数放入变量中。因此这段代码的主要部分实际上是一个存储在 var gameOfLife 中的函数定义,以后可以通过调用来使用:

    gameOfLife()
    

    gol 是一个对象(散列),“init”是上述语法的另一个示例,除了直接放入“gol”散列中的“init”键之外。所以 that 函数可以依次被调用:

    gol["init"](w,h)
    

    【讨论】:

      【解决方案7】:

      如果您希望函数成为对象的属性,将函数视为变量可能会很有用。 (见:http://www.permadi.com/tutorial/jsFunc/index.html)

      我相信 gol 是一个以名称/值对描述的 JavaScript 对象——很像 JSON 格式。 (见:http://www.hunlock.com/blogs/Mastering_JSON_(_JavaScript_Object_Notation_))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-30
        • 2018-01-06
        • 2010-09-25
        • 2011-04-12
        • 2017-08-06
        • 2021-08-22
        相关资源
        最近更新 更多