这里要注意的重要一点是,由于Javascript是一种动态语言,因此每个对象从本质上来说只是一个美化的哈希表(有一些例外)。Javascript对象中的所有内容都可以通过两种方式访问-括号表示法和点表示法。
我将快速回答这两个符号,以回答您问题的第一部分,然后进入第二部分。
括号符号
此模式与访问其他编程语言中的哈希图和数组更相似。您可以访问任何使用此语法组件(数据(包括其他对象)或函数)。
这正是您在示例中所做的。您有'a'
,这是一个字符串(而不是字符文字,就像使用C ++这样的语言一样)。
使用方括号符号,可以访问其toUpperCase
方法。但是访问它仍然是不够的。alert
例如,仅在Java语言中键入,就不会调用该方法。这只是一个简单的声明。为了调用该函数,您需要添加括号:alert()
显示一个包含的简单对话框undefined
,因为该对话框未接收任何参数。现在,我们可以使用此知识来解密您的代码,该代码将变为:
alert('a'.toUpperCase());
更具可读性。
实际上,更好地理解这一点的一种好方法是执行以下Javascript:
alert(alert)
这alert
通过向其传递一个函数对象(也称为)来调用alert
,而不执行第二个警报。显示的内容(至少在Chrome 26中为):
function alert() { [native code] }
致电:
alert(alert())
显示两个连续的消息框,其中包含undefined
。这很容易解释:alert()
首先执行内部,然后显示undefined
(因为它没有任何参数)并且什么都不返回。外部警报接收内部警报的返回值-该值为空,也显示undefined
在消息框中。
在jsFiddle上尝试所有案例!
点表示法
这是更标准的方法,它允许使用dot(.
)运算符访问对象的成员。这是您的代码在点表示法中的样子:
alert('a'.toUpperCase())
更具可读性。那么什么时候应该使用点号表示法,什么时候应该使用括号表示法?
比较方式
两种方法之间的主要区别是语义。还有其他一些细节,我将在稍后讨论。最重要的是您实际想要做的事情-一条经验法则是,将点表示法用于对象具有的完善字段和方法,以及将括号实际用作对象作为哈希图时的括号表示法。
在您的示例中可以看到一个很好的例子说明了为什么此规则如此重要的原因-由于代码在点符号会更敏感的地方使用括号符号,因此使代码更难阅读。这是一件坏事,因为代码被读取的次数比编写的次数多。
在某些情况下,即使使用点符号更明智,也必须使用括号符号:
例:
for(var i = 0; i < 10; ++i) {
foo["method" + i]();
}
最重要的是,在将对象用作哈希映射(foods["burger"].eat()
)时应使用方括号语法,在使用“实际”字段和方法(enemy.kill()
)时应使用点语法。由于Javascript是一种动态语言,因此对象的“实际”字段和方法与存储在其中的“其他”数据之间的界限会变得很模糊。但是,只要您不以混乱的方式混合它们,就可以了。
现在,到您的问题的其余部分(终于!:P)。
我如何确定方法将始终是obj的成员
你不能 试试吧。尝试调用derp
一个字符串。您将在以下行中得到错误:
Uncaught TypeError: Object a has no method 'derp'
在ANY对象上调用ANY方法是一种通用函数。但这是否意味着指定的方法将已经是指定对象的隐式成员?
是的,您的情况必须如此。否则,您将遇到我上面提到的错误。但是,你不必须使用return obj[method]();
的callMethod()
功能。您可以添加自己的功能,然后由map函数使用。这是一个硬编码的方法,可以将所有字母转换为大写字母:
function makeCap()
{
return function(obj) {
return obj.toUpperCase();
}
}
var caps2 = map(['a', 'b', 'c'], makeCap()); // ['A','B','C']
console.log(caps2)
您链接到的教程中的代码使用部分函数。它们本身就是一个棘手的概念。阅读更多有关该主题的内容应该可以使事情比我以前所知道的更清晰。
注意:这是问题代码所使用的map函数的代码,请参见此处。
function map(arr, iterator) {
var narr = [];
for (var i = 0; i < arr.length; i++) narr.push(iterator(arr[i], i));
return narr;
}
arr[5]
。如果数字是有效标识符的名称,则可以使用点符号:arr.5
。