JavaScript一直让我惊讶,这是另一个例子。我只是遇到了一些代码,一开始我不理解。所以我对它进行了调试,得到了这样的发现:

alert('a'['toUpperCase']());  //alerts 'A'

现在,如果toUpperCase()被定义为string类型的成员,这肯定是显而易见的,但最初对我来说没有意义。

不管怎么说,

does this work because toUpperCase is a member of 'a'? Or there is something else going on behind the scenes? the code I was reading has a function as follows: function callMethod(method) { return function (obj) { return obj[method](); //**how can I be sure method will always be a member of obj** } } var caps2 = map(['a', 'b', 'c'], callMethod('toUpperCase')); // ['A','B','C'] // ignoring details of map() function which essentially calls methods on every // element of the array and forms another array of result and returns it It is kinda generic function to call ANY methods on ANY object. But does that mean the specified method will already be an implicit member of the specified object?

我确信我对JavaScript函数的基本概念缺少一些认真的理解。请帮助我理解这一点。


当前回答

但这是否意味着指定的方法已经是指定对象的隐式成员?

不。有人可以传入一个对象

没有名为toUpperCase的属性;或 有一个名为toUpperCase的属性,不是一个函数

在第一种情况下,将抛出一个错误,因为访问不存在的属性将返回undefined,并且我们不能将undefined作为函数调用。

在第二种情况下,将抛出一个错误,因为我们不能将非函数作为函数调用。

请记住,JavaScript是一种非常松散类型的语言。除非必须进行类型检查,否则很少或根本不进行类型检查。您展示的代码在某些情况下是有效的,因为在这些情况下,传递的对象有一个名为toUpperCase的属性,这是一个函数。

可以这么说,obj参数不能保证具有正确类型的属性这一事实根本不会影响JavaScript。它采用“等待和观察”的态度,直到在运行时出现实际问题时才抛出错误。

其他回答

foo。Bar和foo[' Bar ']是相等的,所以你发布的代码是相同的

alert('a'.toUpperCase())

当使用foo[bar](注意没有引号)时,你不使用文字名称bar,而是使用变量bar包含的任何值。所以使用foo[]符号来代替foo。允许您使用动态属性名。


让我们来看看callMethod:

首先,它返回一个以obj为参数的函数。当函数执行时,它将调用该对象上的方法。因此,给定的方法只需要存在于obj本身或它的原型链上的某个地方。

在toUpperCase的情况下,该方法来自string .prototype.toUpperCase -为每个存在的字符串都有一个单独的方法副本是相当愚蠢的。

但这是否意味着指定的方法已经是指定对象的隐式成员?

不。有人可以传入一个对象

没有名为toUpperCase的属性;或 有一个名为toUpperCase的属性,不是一个函数

在第一种情况下,将抛出一个错误,因为访问不存在的属性将返回undefined,并且我们不能将undefined作为函数调用。

在第二种情况下,将抛出一个错误,因为我们不能将非函数作为函数调用。

请记住,JavaScript是一种非常松散类型的语言。除非必须进行类型检查,否则很少或根本不进行类型检查。您展示的代码在某些情况下是有效的,因为在这些情况下,传递的对象有一个名为toUpperCase的属性,这是一个函数。

可以这么说,obj参数不能保证具有正确类型的属性这一事实根本不会影响JavaScript。它采用“等待和观察”的态度,直到在运行时出现实际问题时才抛出错误。

toUpperCase是一个标准的javascript方法:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toUpperCase

它像'a'['toUpperCase']()一样工作的原因是toUpperCase函数是字符串对象'a'的属性。可以使用object[property]或object.property引用对象的属性。语法'a " toUpperCase'表示您正在引用'a'字符串对象的'toUpperCase'属性,然后调用它()。

您可以使用.propertyName表示法或["propertyName"]表示法访问任何对象的成员。这就是JavaScript语言的特点。为了确保该成员在对象中,只需检查它是否被定义:

function callMethod(method) {
    return function (obj) {
        if (typeof(obj[method]) == 'function') //in that case, check if it is a function
           return obj[method](); //and then invoke it
    }
}

javascript中几乎所有的东西都可以被当作对象。在你的例子中,字母本身充当一个字符串对象,toUpperCase可以作为它的方法被调用。方括号只是访问对象属性的另一种方式,由于toUpperCase是一个方法,因此需要在['toUpperCase']旁边使用simple括号(),形成['toUpperCase']()。

'a'['toUpperCase']()相当于'a'.toUpperCase()

'a'['toUpperCase']() // returns A
'a'.toUpperCase() // returns A