为什么需要在该函数内部评估`this`关键字?

4

有人能帮我解释一下这段代码中 this 关键字的作用吗?我正在阅读《JavaScript权威指南》,遇到了这个问题:

// Define the ES5 String.trim() method if one does not already exist.
// This method returns a string with whitespace removed from the start and end.
String.prototype.trim = String.prototype.trim || function() 
{
   if (!this) 
    return this; // WHY EVALUATE `this` IN THIS FUNCTION???

    return this.replace(/^\s+|\s+$/g, "");
};

@elclanrs,但是这个trim方法已经从String类中扩展了,为什么我们需要再次评估它是否是一个String对象呢? - babygau
那个测试基本上毫无益处,而且只会破坏原生的.trim()方法的预期语义。你应该将其删除。“...权威指南”... 是啊,好吧。 - cookie monster
2个回答

5

好的,这是一个测试。

if (!this) return this;

如果字符串为空,则返回this,在这种情况下是一个空字符串。

如果删除此测试,该函数仍然可以正常工作,但保留它将使函数更快,因为在字符串为空时不必调用replace函数。

请注意,此测试if (!this) return this;不适用于nullundefined值,因为它们内部没有可调用的函数,证明是我们不能只这样做:

undefined.trim();
null.trim();

谢谢你,@Khalid,我明白了! - babygau
@babygau,Khalid:这真的不太对。除非在严格模式下,无论字符串是什么,this值都将是“truthy”,因此不会返回this。原因是this不是一个string原始类型,而是一个String对象包装器。如果它在严格模式下,则.trim()方法将被本地支持。因此,您应该删除此测试,因为它没有意义,只会增加不必要的开销。 - cookie monster
此外,在严格模式下,this可以是nullundefined。正确的方式不是做 return this ,而是根据ECMAScript的要求抛出正确的错误。 - cookie monster
此外,在严格模式下,还有其他“falsey”值应该返回它们的 toString() 值,而不是返回原始值。这实际上只会更加破坏事情,永远不会真正提供任何实际的好处。只有在严格模式下,当空原始字符串上调用该方法时,.replace() 将被避免... 而这样做的好处可能不存在。但同样,在支持严格模式的浏览器中,它们已经有了 .trim() 方法。 - cookie monster
抱歉伙计,但是这个答案几乎所有的东西都是错误的。我不知道为什么有六个人给了它+1。 :-( - cookie monster

-1

如果thisundefinednull,那么很可能它会作为错误检测的功能。

if (!string.trim()) { alert("string is null or undefined."); }

2
undefined或null内部没有可调用的函数。 - Khalid
在严格模式下,String.prototype.trim.call(null)会返回null - cookie monster

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