#javascript
#javascript
Вопрос:
Когда я использую call()
или apply()
, у меня возникла проблема.
console.log(String.prototype.replace === String.replace);//false
Я думаю, String.replace
должно быть равно String.prototype.replace
, потому что это один и тот же Объект.
Однако они отличаются друг от друга.
Что происходит, когда я запускаю приведенный ниже код:
var s = "a b c";
String.replace.call(s,'a','A');//return "a"
Почему этот код не выдает ошибку, но возвращает значение?
Комментарии:
1. очевидно, что во внутренних компонентах прототипа есть некоторые улучшения, просто потому, что он обычно возвращает тот же результат…
2.
String.replace.call(s,'a','A');
выдает ошибку, потому что это не функция. Что произойдет, если выполнитьString.replace
без()
? Какой код вы получаете?3. @pimvdb я запускаю этот код в Firefox,String.replace возвращает функцию replace() { [собственный код]} . кроме того, он не выдает ошибку.
Ответ №1:
Я думаю, что здесь много противоречивой информации. Прежде всего, мы должны уточнить, что String
функция-конструктор не имеет replace
метода.
Итак, что бы String.replace
ни было в Firefox, это нестандартно, и поэтому вам следует держаться от этого подальше. Быстрый тест в Chrome показывает, что String.replace
этого там действительно не существует.
К сожалению, я не могу сказать вам, откуда String.replace
берется в Firefox. В документации это не упоминается. Но, похоже, это не наследуемое имущество, так как String.hasOwnProperty('replace')
возвращается true
.
Теперь к некоторым моментам в вашем вопросе:
Я думаю,
String.replace
должно быть равноString.prototype.replace
, потому что это один и тот же Объект.
Очевидно, что это не так. Если бы они были, он вернул бы true
. Также: String !== String.prototype
.
replace
Метод , который используется экземплярами string , является String.prototype.replace
. Так что, если вы хотите использовать call
или apply
, вам подойдет этот метод.
Почему этот код не выдает ошибку, но возвращает значение?
Чтобы ответить на этот вопрос, нам нужно было бы знать, что делает этот метод. Возможно, просмотр источника Firefox или Spidermonkey предоставит некоторую информацию.
Если вы не понимаете, как работает наследование прототипов, ознакомьтесь с Руководством MDN по JavaScript — Подробности о пересмотренной объектной модели и наследовании.
Ответ №2:
Синтаксис replace()
метода является string.replace()
, где string
должна быть строка, не объект String.
Комментарии:
1. Объект String допустим, но
String.replace
не существует. ИтакString.replace == undefined
.
Ответ №3:
Это будет верно:
(new String()).replace === String.prototype.replace
И это не приведет:
String.prototype.replace === String.replace
String
это конструктор, это просто функция.
String.prototype
это объект, в котором другие объекты, созданные с new String()
, будут искать свойства, если у них их не будет.
new String()
создает новый объект. Рассмотрим это:
var s = new String();
s.replace(...);
На самом деле s
не имеет метода замены. По прототипу его конструктор имеет, поэтому вызов этого метода будет успешным.
Ответ №4:
Взгляните на этот jsfiddle http://jsfiddle.net/GmFmR /. По крайней мере, в Chrome это не одно и то же.
String.replace() принимает первый аргумент в качестве строки, которую он будет искать для замены, а затем использует остальные аргументы и загружает их в String.prototype.replace() с помощью method.apply
Редактировать:
В вашем комментарии для получения более подробной информации
Строка.заменить()
function (item){
return method.apply(item, slice.call(arguments, 1));
}
String.prototype.replace()
function replace() { [native code] }
Это то, что приведенный выше jsfiddle отображает в консоли Chrome.
Комментарии:
1. Вы ошибаетесь. В вашей скрипке
String.replace
есть метод, добавленный Mootools. Взгляните на эту скрипку, которая не включает в себя никаких библиотек: jsfiddle.net/GmFmR/12. Моя ошибка, я знал, что это не было частью core framework, поэтому я предположил, что это было что-то добавленное Chrome, поскольку это был браузер, который я использовал