1)在以下代码中,将gameOfLive
变为function gameOfLife()
而不只是gol
背后的原因是什么?
2)什么是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*");
}
},
}
}
?它看起来像一个数组,但我不熟悉语法或它所谓的。
我正在学习http://sixfoottallrabbit.co.uk/gameoflife/
{{1}}
答案 0 :(得分:15)
在JavaScript中,函数为first class objects。您可以将它们存储在对象(变量)中,并将它们作为参数传递给函数。每个函数实际上都是Function
对象。
gol
是一个对象,使用object literal表示法进行初始化。
答案 1 :(得分:15)
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,尝试给出函数分配给的变量的名称,但是由于调试器必须通过动态解析脚本内容来猜测这一点,这可能太难了(导致显示(?)()
,而不是功能名称)甚至是错误的。
(例如,在页面上阅读,但其内容并不完全适合初学者)
答案 2 :(得分:4)
1)在下面的代码中,将gameOfLive变为变量而不仅仅是“函数gameOfLife()”背后的原因是什么?
在全局级别定义的变量是window对象的成员。因此,通过使其成为变量,您可以使用语法window.gameOfLife()
。这也是他们可以在您的代码段开头使用if (!window.gameOfLife)
检查的原因。
但这并没有真正解释为什么他们选择这样做,而功能声明会做同样的事情。 Marcel Korpel's answer更好地解释了两个选项的“原因”。
2)什么是gol?它看起来像一个数组,但我不熟悉语法或它所谓的。
语法称为紧凑对象表示法。这里有趣的是,“compact”对象在函数内声明。在这样的函数内声明一个对象很有用,因为你可以使用它来构建具有(有效)私有成员的javascript对象。
关键是要记住javascript 中的函数和对象是同一个东西。因此,完整的gameOfLife()
函数实际上是一个对象定义。此外,声明为gol
成员的gameOfLife
对象很可能是定义私有成员的常用技术的一部分。 gameOfLife()
函数/对象将返回此gol
对象。在gameOfLife()
函数/对象中声明的所有其他项实际上成为返回的gol
实例的私有成员,而在gol
对象内部声明的所有内容都是公共的。他们真正想做的是最终编写如下代码:
var game = new gameOfLife();
现在,当他们这样做时,游戏变量将保留gol
个对象。此对象中的方法仍然可以访问在完整gameOfLife()
函数中声明的项目,但其他代码却没有(至少不那么容易)。因此,这些物品实际上是私人的。 gol
对象本身的项目仍然是公开的。因此,您有一个包含私有和公共成员的对象,用于正确的封装/信息隐藏,就像您使用其他面向对象语言构建一样。
答案 3 :(得分:2)
将函数放在变量中允许您稍后出现并将其替换为另一个函数,将函数透明地替换为其余代码。当您在表单小部件上指定“onClick =”时,这与您正在执行的操作相同。
答案 4 :(得分:1)
确定:解释语法:
函数是javascript中的第一类对象,因此可以将函数放入变量中。因此,这段代码的主要部分实际上是一个存储在var gameOfLife中的函数定义,以后可以通过调用它来使用:
gameOfLife()
gol是一个对象(哈希),“init”是上述语法的另一个例子,除了直接放入“gol”哈希中的“init”键。所以 函数又可以通过以下方式调用:
gol["init"](w,h)
答案 5 :(得分:1)
根据this page,以他们的方式声明gameOfLife
与宣布自己的方式没有什么不同。他们定义gol
的方式使它成为一个对象(或者你可以把它想象成一个关联数组)。数组的类似快捷方式是使用方括号而不是花括号。
答案 6 :(得分:0)
如果您希望函数成为Object的属性,则将函数视为变量可能很有用。 (见:http://www.permadi.com/tutorial/jsFunc/index.html)
我相信gol是一个用名称/值对描述的JavaScript对象 - 很像JSON格式。 (见:http://www.hunlock.com/blogs/Mastering_JSON_(_JavaScript_Object_Notation_))