2015-01-02 9 views
5

Ich versuche String zu erweitern, um einen Hash von sich selbst zu bieten. Ich verwende die Node.js Crypto-Bibliothek.Warum bezieht sich "this" in String.prototype auf einen Objekttyp, nicht auf einen Stringtyp?

Ich erweitere Zeichenfolge wie folgt:

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

und ich habe eine getHash Funktion, die wie folgt aussieht:

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; 
} 

Die Funktion funktioniert gut, wenn sie direkt aufgerufen, wie in

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

aber wenn ich versuche:

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

Der Methodenaufruf schlägt fehl. Es scheint, dass this in der String.prototype.hashCode als ein Objekt identifiziert wird, wenn crypto.hash.update aufgerufen wird, aber eine Zeichenfolge erwartet wird. Ich dachte, dass this innerhalb String.prototype wäre die Zeichenfolge selbst, aber aus irgendeinem Grund sieht es aus wie ein Objekt getHash(). Wie kann ich es reparieren?

Antwort

7

this kann nicht außerhalb von strict mode einen primitiven Typ sein, so wird es ein Stringwrapper type, die überhaupt wie eine primitive Saite verhält sich nicht (vor allem was typeof und Gleichheit - beide streng und locker - gehen). Sie können es Stimmen:

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

wo '' + verwendet wird, einen beliebigen Wert auf eine primitive Zeichenfolge zu werfen. (String(this) funktioniert auch, wenn Sie das Gefühl, dass es klarer.)

Sie können auch in der Strict-Modus gehen, wo die Dinge nur Sinn machen:

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

Ich würde nur mit 'verwenden strikt' gehen, aber immer noch einen Kommentar zu erklären, warum es erforderlich ist. Es ist wahrscheinlich, dass die meisten Betreuer den Grund nicht kennen. – Marcelo

2

Wenn Sie auf eine Variable primitiver eine Methode aufrufen Typ, so genannte Auto-Boxen erfolgt ist. Dieser Prozess umschließt einen Grundelementwert in das entsprechende Objekt, z. B. 'asdf' bis new String('asdf'). Da technisch primitive Werte keine Methoden und Eigenschaften haben, werden sie in Objektprototypen gehostet. Beim automatischen Boxen können Sie Methoden für primitive Werte aufrufen. Und innerhalb einer Methode ist this immer das Objekt, das diese Methode hat.

Wenn Sie auf den primitiven Wert in einer Methode zugreifen möchten, können Sie ihn entweder als Argument übergeben oder nach Belieben einen primitiven Wert von this abrufen. Zum Beispiel:

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 
Verwandte Themen