Добавление кода в нативные функции
То есть при вызове Math.pow(1,2); в консоль пишется ‘USE: Math.pow’ и возвращается 100500 . Надо сделать так, чтобы функция писала в консоль и продолжала свою «правильную» работу. Я пишу «юзерскрипт» и хочу знать какие методы использует сайт. Не все, конечно, а, например, только из Math .
for (var i in Math ) < eval('Math.__defineGetter__( "' + i + '", function() < console.log( "USE Math.' + i + '" ); return 1; >);'); >
Сейчас я могу это узнать, в консоль всё пишет, но функции не работают и вызывают ошибки.
Отслеживать
19.1k 6 6 золотых знаков 30 30 серебряных знаков 44 44 бронзовых знака
задан 24 июн 2015 в 13:02
wolter_white wolter_white
295 2 2 серебряных знака 12 12 бронзовых знаков
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Простой пример с Math.pow() для демонстрации идеи:
var savedPow = Math.pow; Math.pow = function(number, exp) < console.log('USE: Math.pow'); return savedPow(number, exp); >; console.log(Math.pow(10, 3));
Отслеживать
ответ дан 24 июн 2015 в 13:11
19.1k 6 6 золотых знаков 30 30 серебряных знаков 44 44 бронзовых знака
Спасибо 🙂 Буду делать исходя из Вашего кода!
24 июн 2015 в 13:56
@wolter_white на здоровье. for (var key in Math ) < . >у меня почему-то не работает, поэтому полный пример не сделаю. Единственное что могу ещё сказать — вместо передачи number и exp можно в saved передавать просто массив arguments . Пример в fiddle. Так сказать, универсальный вариант для всех функций.
Функция PFN_WEB_CORE_ACTIVATE
pszAppHostConfigFile
Указатель на строку, содержащую путь к файлу конфигурации.
pszRootWebConfigFile
Указатель на строку, содержащую путь к корневому файлу Web.config. (необязательно)
pszInstanceName
Указатель на строку, содержащую имя экземпляра, который будет использоваться для ведения журнала событий.
Возвращаемое значение
Объект HRESULT . Допустимые значения включают, но не ограничиваются, значения, приведенные в следующей таблице.
| Значение | Описание: |
|---|---|
| S_OK | Указывает, что операция выполнена успешно. |
| ERROR_SERVICE_ALREADY_RUNNING | Указывает, что экземпляр размещенного веб-ядра уже запущен в процессе. |
| ERROR_INVALID_DATA | Указывает, что в файле конфигурации произошла ошибка. |
PFN_WEB_CORE_ACTIVATE Если функция возвращает сообщение ERROR_INVALID_DATA, Просмотр событий может содержать дополнительные сведения о причине сбоя.
Комментарии
Функция PFN_WEB_CORE_ACTIVATE является прототипом точки WebCoreActivate входа DLL в Hwebcore.dll, которая используется для запуска размещенного веб-ядра. Процесс, в котором размещается веб-ядро, требуется для предоставления пути к файлу конфигурации, который содержит параметры конфигурации для всех создаваемых сайтов, пула приложений и т. д.
Для hosted Web Core требуется файл конфигурации, соответствующий структуре файла ApplicationHost.config, за исключением того, что hosted Web Core поддерживает только один пул приложений. Дополнительные сведения о создании файла конфигурации для приложения см. в разделе Пошаговое руководство. Создание файла конфигурации для размещенного веб-ядра.
Для этой функции также требуется имя экземпляра размещенного веб-ядра, которое iis 7 использует при регистрации событий в Просмотр событий. При необходимости процесс размещения может предоставить путь к корневому Web.config файлу, содержащему дополнительные параметры.
Требования
| Тип | Описание |
|---|---|
| клиент | — IIS 7.0 в Windows Vista — IIS 7.5 в Windows 7 — IIS 8.0 в Windows 8 — IIS 10.0 в Windows 10 |
| Сервер | — IIS 7.0 в Windows Server 2008 — IIS 7.5 в Windows Server 2008 R2 — IIS 8.0 в Windows Server 2012 — IIS 8.5 в Windows Server 2012 R2 — IIS 10.0 в Windows Server 2016 |
| Продукт | — IIS 7.0, IIS 7.5, IIS 8.0, IIS 8.5, IIS 10.0 — IIS Express 7.5, IIS Express 8.0, IIS Express 10.0 |
| Заголовок | Hwebcore.h |
Native Script. Один код для всех платформ
Native script (NS) – это библиотека, позволяющая делать кросс-платформенные приложения, используя XML, CSS, JavaScript. Native script решает ту же задачу, что и уже всем известный phonegap (создание кросс-платформенных приложений), но подходы у них разные. Phonegap использует движок браузера, чтобы отобразить ваш UI (фактически вы получаете веб-страницу), Native script использует нативный рендеринг, использует элементы нативного UI. Следующее важное отличие: чтобы получить доступ к камере, gps и так далее в phonegap необходимо устанавливать плагины, в то время как NS дает доступ из коробки.
Стоит подчеркнуть, что приложения можно писать для Android 4.2 и выше, и для iOS 7.1 и выше.
Быстрый старт
Чтобы установить native script, необходим nodejs, поэтому если у вас еще нет его, отправляйтесь сюда. Дальше все просто. Для установки NS в командной строке выполняем:
npm install -g nativescript
Для создания проекта:
tns create MyApp
После того, как проект создался, переходим в директорию проекта:
cd MyApp
И, как и в phonegap, добавляем платформы:
tns platform add android tns platform add ios
Все готово, чтобы запустить наше первое native script приложение. Для того чтобы сделать это, нужно вести одну из следующих команд:
Запустить на устройстве, подключенном через USB:
tns run android
Запустить в эмуляторе:
tns run android --emulator
Можно также запустить в Genymotion:
tns run android --geny
В общем, как бы вы не запускали, у вас откроется приложение, которое подсчитывает количество нажатий на кнопку, оставшихся до вывода текста «Hoorraaay! You unlocked the NativeScript clicker achievement!».

Вот сравнение как выглядит приложение на iOS и Android.

Как можно заметить, кнопка везде нативная, хотя код для обоих платформ один и тот же.
Что там внутри?
Структура проекта представлена ниже:

Все, что касается вида приложения, лежит в файле main-page.xml. Всех, кто привык работать с html, ужаснет этот файл, но благо документация очень хорошая, и чуть позже все становится понятнее.
>" /> >" cssClass="message" textWrap="true"/>
app.js – точка входа в приложение. В NS используются модули, так же как и nodejs. Думаю, тут все итак понятно.
var application = require("application"); application.mainModule = "main-page"; application.cssFile = "./app.css"; application.start();
main-page.js – содержит код для main-page.xml.
var vmModule = require("./main-view-model"); function pageLoaded(args) < var page = args.object; page.bindingContext = vmModule.mainViewModel; >exports.pageLoaded = pageLoaded;
Функция pageLoaded будет выполнена, в момент загрузки страницы (см. main-page.xml). Строка page.bindingContext = vmModule.mainViewModel устанавливает binding контекст для данной страницы (что-то наподобие $scope в ангуляр). Ну и последняя строка экспортирует функцию.
Следующий файл, main-view-model.js, позволит подробнее рассмотреть механизм data binding в NS. NS поддерживает two-way и one-way binding.
var __extends = this.__extends || function (d, b) < for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() < this.constructor = d; >__.prototype = b.prototype; d.prototype = new __(); >; var observable = require("data/observable"); var HelloWorldModel = (function (_super) < __extends(HelloWorldModel, _super); function HelloWorldModel() < _super.call(this); this.counter = 42; this.set("message", this.counter + " taps left"); >HelloWorldModel.prototype.tapAction = function () < this.counter--; if (this.counter else < this.set("message", this.counter + " taps left"); >>; return HelloWorldModel; >)(observable.Observable); exports.HelloWorldModel = HelloWorldModel; exports.mainViewModel = new HelloWorldModel();
Чтобы dataBinding работал, в NS объект должен выбрасывать событие propertyChange. Это реализовано в классе Observable. В нашем случае он передается в функцию, в которой HelloWorldModel наследует его. Дальше уже через метод set полям присваиваются значения. Функция __extends в самом верху файла служит для осуществления наследования.
Проверим двухсторонний binding в деле. Добавим в main-page.xml две строчки перед тегом .
>" hint="введите ваше имя"/> >" text=">"/>
В файле main-view-model.js в функцию HelloWorldModel добавим строку:
this.set("name", "");
И наконец в app.css. Стоит подчеркнуть, что поддерживаются далеко не все CSS свойства, полный список можно найти тут.
.hidden
В итоге получим:

Заключение
Native script для меня, как для веб-разработчика, оставил смешанные чувства. С одной стороны, видно, что авторы старались сделать все близко к вебу (JavaScript, CSS), но с другой, CSS свойства поддерживаются не все, чтобы разобраться с XML приходится постоянно лезть в документацию. Возможно NS решит проблемы, которые есть в phonegap, где то тут, то там появляются какие-то сложности, связанные с веб происхождением приложения. В любом случае, это круто, что появился еще один фреймворк, позволяющим знающим JavaScript писать кросс-платформенные приложения, т.к. на этом рынке становится тесно (phoneGap, Native Script, React Native) и как следствие качество фреймворков должно улучшаться.
- Веб-разработка
- CSS
- JavaScript
- Разработка мобильных приложений
Как в JavaScript определить, является ли функция нативной
Время от времени мне приходится проверять, является ли та или иная функция нативной — это важная часть проверки, была ли функция предоставлена браузером или это порождение постороннего шима, замаскированное под встроенный компонент. Лучший способ выполнения такой проверки — это, конечно же, оценка значения toString , возвращённого функцией.
JavaScript
Код, требуемый для этого, довольно прост:
function isNative(fn) < return (/\/).test('' + fn); >
Вся суть состоит в том, чтобы конвертировать функцию в строчное представление и выполнить сопоставление строки с регулярными выражениями. Лучшего способа подтвердить, что это нативная функция, не существует!
Обновление!
Создатель библиотеки lodash, Джон-Дэвид Далтон (John-David Dalton), предложил лучшее решение:
;(function( ) < // Используется для разложения на составляющие внутреннего `[[Class]]` значений var toString = Object.prototype.toString; // Используется для разложения на составляющие декомпилированного // исходного кода функции var fnToString = Function.prototype.toString; // Используется для определения конструкторов среды (Safari > 4; // по сути, предназначено специально для типизированных массивов) var reHostCtor = /^\[object .+?Constructor\]$/; // Составление регулярного выражения на основе часто употребляемого // нативного метода в качестве шаблона. // Выбираем `Object#toString`, так как вполне вероятно, что он ещё не задействован. var reNative = RegExp('^' + // Применяем `Object#toString` к строке String(toString) // Избавляемся от любых специальных символов регулярных выражений .replace(/[.*+?^$<>()|[\]\/\\]/g, '\\$&') // Заменяем упоминания `toString` на `.*?`, чтобы сохранить обобщённый вид шаблона. // Заменяем `for . ` и тому подобное для поддержки окружений вроде Rhino, // которые добавляют дополнительную информацию, такую как арность метода. .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); function isNative(value) < var type = typeof value; return type == 'function' // Используем `Function#toString`, чтобы обойти собственный метод // `toString` самого значения и избежать ложного результата. ? reNative.test(fnToString.call(value)) // На всякий случай выполняем проверку на наличие объектов среды, так // как некоторые окружения могут представлять компоненты вроде // типизированных массивов как методы DOM, что может не соответствовать // нормальному нативному паттерну. : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false; > // экспортируем в удобном для вас виде module.exports = isNative; >());
И вот теперь у нас точно есть лучший подход для определения, является ли метод нативным. Естественно, не стоит использовать его для обеспечения безопасности — это лишь признак того, что функция нативна.
