Javascript中使用apply或call方法对charCodeAt进行调用

5
前提条件:正确的 charCodeAt(i : Int) 性能应该是什么样子的:
"test".charCodeAt(0)
116
"test".charCodeAt(1)
101
"test".charCodeAt(2)
115
"test".charCodeAt(3)
116
"test".charCodeAt(4)
NaN

使用call或apply时会发生什么:

>"test".charCodeAt.apply(this, [0,1,2,3])
91
//that's fine, except for 91!
"test".charCodeAt.call(this,0)
91
"test".charCodeAt.call(this,4)
101
"test".charCodeAt.call(this,5)
99
"test".charCodeAt.call(this,50)
NaN
"test".charCodeAt.call(this,6)
116
"test".charCodeAt.call(this,8)
68

x = "test".charCodeAt
function charCodeAt() { [native code] }
x.call(x,0)
102

参数被正确传递。关键在于使用call或apply的第一个参数所传递的作用域,并且改变了this指针的valueOf。

我不太确定发生了什么,而且无法在新的控制台窗口(Chrome v15)中重现这种行为:

x = "test"
"test"

"".charCodeAt.call(this.x,0)
116
OK.

关于这个问题:当范围没有用`this.x`指定而只用`x`来表示时-在这个例子中,由于JS解释器的范围解析,会导致奇怪的行为吗?是否有人遇到过类似的范围冲突的问题?

我刚刚看了你的博客,你正在扩展主机对象的原型。这通常是很危险的。对于 String 来说是安全的,但请永远不要尝试对 ArrayObject 进行扩展。 - ThiefMaster
@ThiefMaster,嗯,这可能不是每个人都喜欢做的事情,但一些库(如Functional、Prototype)使用本地对象的扩展作为基本的架构方法。 - Pointy
2个回答

6

在所有这些类似的调用中:

"test".charCodeAt.call(this, 0);

this的值很可能是window,而不是任何字符串值。试一下这个:

var string = "test";
string.charCodeAt.call(string, 0);

如果你将一个虚假的值传递给this,那么就不能期望它能正常工作 :-) 当你定义一个变量"x"并引用"this.x"时,它能够工作的原因是thiswindow,所以"this.x"等同于"window.x",这样就能获取到你的变量了。

@Joey,但这只是一个变量名;“String”是预定义的构造函数名称。 - Pointy
最合适的方法是String.prototype.charCodeAt.call(string, 0) - ThiefMaster
@ThiefMaster 是的,这是正确的。如果出于某种原因希望将函数隔离开来,最好直接从原型对象中获取它。我试图保持与原始问题的平行,以便更清晰明了。 - Pointy

1

this 在你的情况下是 window,并且 window.toString() === "[object Window]"。 所以你正在处理那个字符串。

如果你想更好地使用 charCodeAt 函数,可以使用 var foo = String.prototype.charCodeAt; 然后在某个字符串上调用它:foo.call('meow', 0)


>this.toString() "[object DOMWindow]"完美,这解释了为什么字符串的可访问索引大约是20! - Lorenz Lo Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接