为什么String.prototype里面的'this'指的是对象类型,而不是字符串类型?

Why does 'this' inside String.prototype refer to an object type, not a string type?

我正在尝试扩展字符串以提供其自身的散列。我正在使用 Node.js 加密库。

我这样扩展字符串:

String.prototype.hashCode = function() {
    return getHash(this);
};

我有一个 getHash 函数,如下所示:

function getHash(testString) {
    console.log("type is" + typeof(testString));
    var crypto = require('crypto');
    var hash = crypto.createHash("sha256");
    hash.update(testString);
    var result = hash.digest('hex');
    return result;
}

函数在直接调用时工作正常,如

var s = "Hello world";
console.log(getHash(s));

但是当我尝试时:

var s = "ABCDE";
console.log(s.hashCode());

方法调用失败。看起来 String.prototype.hashCode 中的 this 在调用 crypto.hash.update 时被识别为一个对象,但需要一个字符串。我认为 String.prototype 中的 this 将是字符串本身,但由于某种原因它看起来像 getHash() 的对象。我该如何解决?

this 不能是 strict mode, so it becomes a String wrapper type 之外的原始类型,它的行为根本不像原始字符串(特别是 typeof 和等式 –严格和宽松——去吧)。你可以施放它:

String.prototype.hashCode = function () {
    return getHash(<b>'' +</b> this);
};

其中 '' + 用于将任何值转换为原始字符串。 (String(this)也可以,如果你觉得更清楚的话。)

您也可以进入严格模式,在这种模式下 才有意义:

String.prototype.hashCode = function () {
    'use strict';
    return getHash(this);
};

当您在原始类型的变量上调用方法时,会发生所谓的自动装箱。该过程将原始值包装到相应的对象中,例如 'asdf'new String('asdf')。因为技术上原始值没有 方法 属性 ,所以它们托管在对象原型中。使用自动装箱,您可以调用原始值的方法。在一个方法中,this 始终是具有该方法的 object

如果您想在方法中访问原始值,您可以将其作为参数传递,或者根据需要从 this 中检索原始值。例如:

var str = new String('asdf') // String {0: "a", 1: "s", 2: "d", 3: "f", length: 4, formatUnicorn: function, truncate: function, splitOnLast: function, [[PrimitiveValue]]: "asdf"}
String(str) // 'asdf'

var num = new Number(123) // Number {[[PrimitiveValue]]: 123}
Number(num) // 123

var bool = new Boolean(true) // Boolean {[[PrimitiveValue]]: true}
Boolean(bool) // true