String.prototype "this" не возвращает строку?
Что здесь происходит? Просто, когда я думал, что знаю JS внутри и снаружи, этот камень появляется.
String.prototype.doNothing = function() {
return this;
};
alert(typeof 'foo'.doNothing()) // object
alert(typeof 'foo') // string
http://jsfiddle.net/dJBmf/
Это разбивает некоторые вещи, которые ожидают строку, например метод jQuery .text(str)
.
Ответы
Ответ 1
Вот подробный обзор ключевого слова this
. В принципе, JavaScript преобразует его в объект, если он не один.
Следующие шаги выполняются, когда управление входит в контекст выполнения для кода функции, содержащегося в функциональный объект F, предоставленный вызывающий thisValue, и вызывающий argumentsList:
- Если код функции является строгим кодом, установите для параметра ThisBinding значение thisValue.
- Если значение thisValue равно null или undefined, установите значение ThisBinding для глобальный объект.
- Иначе, если Type (thisValue) не является объектом, установите для параметра ThisBinding значение ToObject (thisValue).
- Else установить ThisBinding для thisValue
То же самое происходит с Numbers и Booleans. Аналогичная функция DoNothing
возвращает тип объекта.
Ответ 2
Чтобы убедиться, что вы всегда получаете строку, пытаясь использовать этот код:
String.prototype.doNothing = function() {
return this.toString();
};
alert(typeof 'foo'.doNothing())
alert(typeof 'foo')
В исходном коде this
возвращается как строковый объект, а не фактическая строка.
Ответ 3
Запустите код в strict
, чтобы получить ожидаемый результат!
Ответ 4
Это опять разница между строковыми литералами и строками, я верю? Я когда-то задал вопрос в SO: Значение свойства объекта String в JavaScript
Ответ 5
Вы также могли бы использовать свойство constructor
:
'foo'.constructor === String; //=>true
'foo'.doNothing().constructor === String; //=>true
См. также этот вопрос SO и этот jsFiddle
Если String.prototype.doNothing()
разбивает материал, ожидающий строковое значение, я бы использовал return String(this)
или this.toString()
(this.valueOf()
также работает здесь).
Ответ 6
Чтобы лучше понять, что происходит, попробуйте использовать консольные журналы, например:
String.prototype.doNothing = function() {
console.log(this);
return this;
};
console.log(typeof 'foo'.doNothing());
console.log(typeof 'foo');
Это результаты, которые я получаю в Firefox:
foo { 0="f", 1="o", more...}
object
string
Итак, в прототипе кажется, что строка представлена как объект/массив символов (что имеет смысл.)
Независимо от того, следует ли использовать toString (как было предложено Макхерби) или кастинг как тип String (как предлагает mellamokb), зависит, на мой взгляд, от того, что вы планируете делать с этим значением. Я лично склоняюсь к тому, чтобы выставить его как String.
Ответ 7
попробуйте следующее:
return this + '';
Ответ 8
function print() {
let str = this;
console.log(str);
}
String.prototype.print = print;
let a = "hello";
a.print();//output:"hello"
Ответ 9
Попробуйте return String(this);
вместо return this;