这里需要注意的重要一点是,由于Javascript是一种动态语言,因此每个对象本质上都只是一个美化过的哈希映射(有少数例外)。Javascript对象中的所有内容都可以通过两种方式访问——括号表示法和点表示法。
我会快速地过一遍这两个符号来回答你问题的第一部分,然后我会讲第二部分。
括号
这种模式更类似于访问其他编程语言中的hashmap和数组。您可以使用此语法访问任何组件(数据(包括其他对象)或函数)。
这正是您在示例中所做的。你有一个'a',它是一个字符串(而不是字符字面量,就像在c++等语言中那样)。
使用括号符号,您可以访问它的toUpperCase方法。但仅仅获取信息还不够;例如,简单地在Javascript中输入alert,并不会调用该方法。这只是一个简单的陈述。为了调用函数,您需要添加圆括号:alert()显示了一个包含undefined的简单对话框,因为它没有接收到参数。我们现在可以利用这些知识来破译你的代码,它变成:
alert('a'.toUpperCase());
这样可读性更强。
实际上,更好地理解这一点的一个好方法是执行以下Javascript:
alert(alert)
它通过传递一个函数对象来调用alert,同样是alert,而不执行第二个alert。所显示的内容(至少在Chrome 26中)如下:
function alert() { [native code] }
调用:
alert(alert())
显示包含undefined的两个连续消息框。这很容易解释:内部alert()首先被执行,显示为undefined(因为它没有任何参数)并且没有返回任何东西。外部警报接收内部警报的返回值-这是空的,并且在消息框中显示为undefined。
在jsFiddle上尝试所有的案例!
点符号
这是一种更标准的方法,允许使用点(.)操作符访问对象的成员。这是你的代码在点表示法下的样子:
alert('a'.toUpperCase())
可读性更强。什么时候用点符号,什么时候用括号符号?
比较
这两种方法的主要区别在于语义。还有一些其他细节,但我马上就会讲到。最重要的是您实际想要做什么——经验法则是,对于对象拥有的已建立的字段和方法使用点表示法,当您实际将对象用作哈希映射时使用括号表示法。
为什么这个规则如此重要的一个很好的例子可以在你的例子中显示出来——因为代码在点表示法更有意义的地方使用了括号表示法,这使得代码更难阅读。这是一件坏事,因为代码被读取的次数要比编写的次数多得多。
在某些情况下,你必须使用括号符号,即使使用点符号更明智:
如果对象成员的名称包含一个或多个空格或任何其他特殊字符,则不能使用点符号:foo。Some method()不起作用,但foo[" Some method"]()起作用;
如果你需要动态访问一个对象的成员,你也会使用括号符号;
例子:
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'
在任意对象上调用任意方法是一种通用函数。但
这是否意味着指定的方法已经是隐式成员
指定对象的?
是的,在你的情况下,它必须是。否则就会出现我上面提到的错误。但是,你不必使用return obj[method]();在callMethod()函数中。您可以添加自己的功能,然后由映射函数使用。下面是一个硬编码的方法,将所有的字母转换为大写字母:
function makeCap()
{
return function(obj) {
return obj.toUpperCase();
}
}
var caps2 = map(['a', 'b', 'c'], makeCap()); // ['A','B','C']
console.log(caps2)
您链接到的教程中的代码使用了部分函数。它们本身就是一个棘手的概念。多读一些这方面的书会让你更清楚一些。
注意:这是问题中代码使用的映射函数的代码,源代码在这里。
function map(arr, iterator) {
var narr = [];
for (var i = 0; i < arr.length; i++) narr.push(iterator(arr[i], i));
return narr;
}