Почему строковая переменная может использовать метод Foreach по вызову JS? -- javascript пол Связанный проблема

Why a string variable can use forEach method by call in JS?


0
vote

проблема

русский

 <Код> var rst = 0;     var num = 0;  Array.prototype.forEach.call(num + '', function(v){ rst += +v; });  

Вы можете увидеть сверху. <Код> num - это номер, то мы преобразуем его в строку <код> num+'' . Консоль не показывает ошибку.

Что заставляет меня запутаться, это то, что <код> num - это строка, почему она может использовать <код> forEach метода?

Английский оригинал

var rst = 0;     var num = 0;  Array.prototype.forEach.call(num + '', function(v){ rst += +v; });

You can see from above. num is a number, then we convert it to string by num+''. The console shows no error.

What make me confused is that num is a string, why it can use the forEach method?

</div
  

Список ответов

2
 
vote

во всех стандартных совместимых реализациях JS любой объект, похожий на массив, может использовать функции из Array.prototype , включая строки:

 <Код> var arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 }; // same as 'abc'    Array.prototype.forEach.call(arrayLike, function(val) {    console.log(val);    });  
 

In all standard compliant JS implementations, any array-like object can use functions from Array.prototype, including strings:

var arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 }; // same as 'abc'    Array.prototype.forEach.call(arrayLike, function(val) {    console.log(val);    });
</div
 
 
         
         
1
 
vote

Вы не звоните <код> forEach функции, которые могут быть членом строкового прототипа. Вы явно вызываете <код> Array Prototype <код> forEach и сообщаете об этом для лечения <код> thisArg как <код> Array . В зависимости от среды выполнения среды выполнения Реализация forEach может быть в зависимости от браузера / окружающей среды, но в худшем случае не будет ничего не делать и молча возвращаться <код> namespace :active_storage do desc "Migrates active storage local files to cloud" task migrate_local_to_cloud: :environment do raise 'Missing storage_config param' if !ENV.has_key?('storage_config') require 'yaml' require 'erb' require 'google/cloud/storage' config_file = Pathname.new(Rails.root.join('config/storage.yml')) configs = YAML.load(ERB.new(config_file.read).result) || {} config = configs[ENV['storage_config']] client = Google::Cloud.storage(config['project'], config['credentials']) bucket = client.bucket(config.fetch('bucket')) ActiveStorage::Blob.find_each do |blob| key = blob.key folder = [key[0..1], key[2..3]].join('/') file_path = Rails.root.join('storage', folder.to_s, key) file = File.open(file_path, 'rb') md5 = Digest::MD5.base64digest(file.read) bucket.create_file(file, key, content_type: blob.content_type, md5: md5) file.close puts key end end end 0 .

Вот какой-то источник из webkit. Существует какой-то код специфики массива, но в целом нет причин, что это не будет работать в значительной степени.

 <код> namespace :active_storage do   desc "Migrates active storage local files to cloud"     task migrate_local_to_cloud: :environment do       raise 'Missing storage_config param' if !ENV.has_key?('storage_config')        require 'yaml'       require 'erb'       require 'google/cloud/storage'        config_file = Pathname.new(Rails.root.join('config/storage.yml'))       configs = YAML.load(ERB.new(config_file.read).result) || {}       config = configs[ENV['storage_config']]        client = Google::Cloud.storage(config['project'], config['credentials'])       bucket = client.bucket(config.fetch('bucket'))        ActiveStorage::Blob.find_each do |blob|         key = blob.key         folder = [key[0..1], key[2..3]].join('/')         file_path = Rails.root.join('storage', folder.to_s, key)         file = File.open(file_path, 'rb')         md5 = Digest::MD5.base64digest(file.read)         bucket.create_file(file, key, content_type: blob.content_type, md5: md5)         file.close         puts key       end     end   end 1  
 

You're not calling the forEach function that might be a member of the String prototype. You're explicitly calling the Array prototype forEach and telling it to treat the thisArg as an Array. Depending on your runtime environment the implementation of forEach may be browser/environment dependent but at worst it's going to do nothing and silently return undefined.

Here's some source from webkit. There is some array specific code, but in general there's no reason it wouldn't work on pretty much anything.

EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec) {     JSObject* thisObj = exec->hostThisValue().toObject(exec);     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);     if (exec->hadException())         return JSValue::encode(jsUndefined());      JSValue function = exec->argument(0);     CallData callData;     CallType callType = getCallData(function, callData);     if (callType == CallTypeNone)         return throwVMTypeError(exec);      JSValue applyThis = exec->argument(1);      unsigned k = 0;     if (callType == CallTypeJS && isJSArray(thisObj)) {         JSFunction* f = jsCast<JSFunction*>(function);         JSArray* array = asArray(thisObj);         CachedCall cachedCall(exec, f, 3);         for (; k < length && !exec->hadException(); ++k) {             if (UNLIKELY(!array->canGetIndexQuickly(k)))                 break;              cachedCall.setThis(applyThis);             cachedCall.setArgument(0, array->getIndexQuickly(k));             cachedCall.setArgument(1, jsNumber(k));             cachedCall.setArgument(2, thisObj);              cachedCall.call();         }     }     for (; k < length && !exec->hadException(); ++k) {         PropertySlot slot(thisObj);         if (!thisObj->getPropertySlot(exec, k, slot))             continue;          MarkedArgumentBuffer eachArguments;         eachArguments.append(slot.getValue(exec, k));         eachArguments.append(jsNumber(k));         eachArguments.append(thisObj);          if (exec->hadException())             return JSValue::encode(jsUndefined());          call(exec, function, callType, callData, applyThis, eachArguments);     }     return JSValue::encode(jsUndefined()); } 
</div
 
 
       
       

Связанный проблема

-1  Откройте диалог поиска поля в CRM 2011 от JavaScript  ( Open the lookup dialog of a field in crm 2011 from javascript ) 
Как я могу запустить диалог поиска поля поиска, используя JavaScript? ...

1  Обработка ошибок METEOR для шаблона именования ошибок опечатки  ( Meteor error handling for template naming typo errors ) 
Недавно у меня была ошибка с именем, используемым в файле помощников. Поскольку используемое имя шаблона было недействительным, все мои глобальные помощники п...

0  SVG D3 круговой контроль  ( Svg d3 circular control ) 
Я пытаюсь сделать контроль, в котором радиальные линии прилипают за пределами круга. Длина каждой линии, прилипающей зависит от значения данных. Короче говоря...

0  Запустить функцию JavaScript с использованием C #  ( Trigger javascript function using c sharp ) 
Я должен написать класс C #, который получает содержимое HTML-страницы (страница публичная) и запускает функцию JavaScript, которая загружает файл. Моя цель...

1  Джейморфизм JavaScript: Как получить доступ к статическим атрибутам наследования класса в статическом методе («абстрактный») базовый класс?  ( Javascript polymorphism how to access static attributes of inheriting class in ) 
Я хотел бы иметь базовый класс и наследственный класс. Базовый класс должен обеспечить некоторую общую функциональность, которая зависит от свойств наследстве...

3  Как реализовать автономный компонент в React Redux?  ( How to implement a self contained component in react redux ) 
Я создаю базу файлового менеджера Webui основы на React Redux (моя цель - это управлять React и Redux через этот проект) Как вы знаете, файловый менеджер ну...

0  Ошибка прокладывания слайдера jQuery: ... не удалось конвертировать аргумент JavaScript ARG 0 [NSIDOMHTMLanChorElement.appendChild]  ( Jquery slider throwing error could not convert javascript argument arg 0 ns ) 
Наш сайт Dev Dev имеет ползунок отлично работает здесь: http://allblacks.01dev.co.nz/index.cfm layout = dnahome Однако мы просто поставили сайт Live, и ...

4  Создание нового пустого документа с JavaScript  ( Creating a new empty document with javascript ) 
Я работаю с некоторыми очень неразрушными XML (все теги - такие вещи, как «TX», «H», «VC»). Я хотел бы сделать копию этих данных, но со всеми тегами переиме...

30  Динамическое имя NG-контроллера  ( Dynamic ng controller name ) 
Я хочу динамически указать контроллер на основе конфигурации, которую мы загружаем. Что-то вроде этого: <код> <div ng-controller="{{config.controllerNameStr...

3  Рисование круга с помощью кинетических js  ( Drawing a circle using kinetic js ) 
Я пытаюсь построить очень базовую покраску, используя каркас kinetic JS. Все все идут хорошо, пока не попытался включить функцию формы, которая позволяет поль...

5  Экспорт SVG в PDF в автономном TideSDK WebApp  ( Exporting svg to pdf in a offline tidesdk webapp ) 
У меня есть приложение Offline HTML5 / CSS / JS, построенное с TIDESDK, в котором гистограмма нарисована с HighCharts в качестве SVG «Tag», используя данные, ...

11  Rx JS понимает метод подъема  ( Rx js understanding the lift method ) 
Я хочу создать новый оператор, и я нахожу в Документация То, что один из способов сделать что-то подобное: <код> class MyObservable extends Observable { ...

0  Как проверить функцию в жасмине  ( How to test a function in jasmine ) 
Может кто-нибудь помочь мне, пожалуйста? Я пытаюсь проверить функцию, которая вызывает функции FireBase, но когда я вызываю основную функцию и начните управля...

12  Синтаксисная ошибка в видом на бритву при прохождении свойств модели в качестве параметров на функцию JavaScript  ( Syntax error in razor view when passing model properties as parameters to javasc ) 
Я получаю <код> Syntax error на каждой запятой (<код> , ) и на последнем кронштейне (<код> ) ) в следующем коде: <код> <script type="text/javascript"> ...

0  Имея проблемы с использованием объема в jQuery  ( Having issues using a scope in jquery ) 
Так что я пытаюсь передать значение переменной FreeMarker ($ {item.uid}) на клик ссылки, чтобы запустить модаль с тем же уникальным значением идентификатора. ...

Связанный проблема

-1  Откройте диалог поиска поля в CRM 2011 от JavaScript 
1  Обработка ошибок METEOR для шаблона именования ошибок опечатки 
0  SVG D3 круговой контроль 
0  Запустить функцию JavaScript с использованием C # 
1  Джейморфизм JavaScript: Как получить доступ к статическим атрибутам наследования класса в статическом методе («абстрактный») базовый класс? 
3  Как реализовать автономный компонент в React Redux? 
0  Ошибка прокладывания слайдера jQuery: ... не удалось конвертировать аргумент JavaScript ARG 0 [NSIDOMHTMLanChorElement.appendChild] 
4  Создание нового пустого документа с JavaScript 
30  Динамическое имя NG-контроллера 
3  Рисование круга с помощью кинетических js 
5  Экспорт SVG в PDF в автономном TideSDK WebApp 
11  Rx JS понимает метод подъема 
0  Как проверить функцию в жасмине 
12  Синтаксисная ошибка в видом на бритву при прохождении свойств модели в качестве параметров на функцию JavaScript 
0  Имея проблемы с использованием объема в jQuery