Строка.прототип.заменить === Строка.заменить

#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/1

2. Моя ошибка, я знал, что это не было частью core framework, поэтому я предположил, что это было что-то добавленное Chrome, поскольку это был браузер, который я использовал