Могу ли я решить, что происходит при вызове метода несуществующих объектов?

У меня есть код, который выглядит так:

obj.foo(); // obj might, or might not have a `foo` method. 

Я хочу знать, могу ли я переопределить то, что происходит, когда obj.foo вызывается в моем коде, например:

 obj.foo = function(){ alert ("Hello"); }); obj.onCallNonExistentMethod = function(){ // I know this is imaginary syntax alert("World"); } obj.foo(); // alerts "Hello" delete obj.foo; obj.foo(); // alerts "World" , would TypeError without the method missing handler. 

Из того, что я понимаю, в Ruby это будет method_missing или const_missing или что-то подобное.

Могу ли я переопределить, что происходит при вызове несуществующего метода объекта в JavaScript? Если смогу, как мне это сделать?

Целью является проверка API, который я предоставляю пользователям, чтобы они могли безопасно использовать API, и я могу более четко их предупредить об ошибках.

  • Как вычесть минуты из даты в javascript?
  • Какие хорошие способы предотвратить обман в многопользовательских играх?
  • Как закрыты и области, представленные во время выполнения в JavaScript
  • Как выполнить запрос PHP для выбора варианта выбора с помощью AJAX?
  • Как я могу получить значения из json и отображать их в javascript
  • Удивлен, что глобальная переменная имеет неопределенное значение в JavaScript
  • Как следует ввести функцию потока lodash в машинописном тексте?
  • Язык и формат даты с помощью Moment.js
  • 4 Solutions collect form web for “Могу ли я решить, что происходит при вызове метода несуществующих объектов?”

    К сожалению, это невозможно в любом широко распространенном виде. Самое близкое, что вы можете получить, это использовать прокси-функцию для всех вызовов, т. foo.invoke('bar') Вместо foo.bar() вы будете использовать что-то вроде foo.invoke('bar') . Однако это довольно уродливо и, скорее всего, близко к тому, что вы имели в виду в первой части «не заинтересованы».

    В свободно типизированных языках довольно часто можно ожидать, что разработчик передаст совместимые объекты, т. Е. Получить сообщение об ошибке при передаче чего-то неожиданного.


    Однако, если вам посчастливилось использовать движок JS, который поддерживает функции ECMAScript-гармонии (очевидно, IE не работает), вы можете использовать объекты прокси для достижения этого. В основном вы переносите свой объект в прокси-сервер, который позволяет захватывать большинство операций над объектом, таких как итерация, извлечение свойства или даже создание свойств. Кроме того, две ссылки, рассматривающие этот ответ на этот вопрос, могут быть полезны.

    Два года назад Бенджамин, ты не очень хорошо понимал понятие поведенческой типизации?

    К счастью для вас, вы скоро поймете, что интерфейс не является структурным в JavaScript с момента написания этого вопроса и даже написал библиотеку, которая решает точный вопрос, о котором вы говорите, но никогда не использовать его.

    Итак, чтобы ответить на ваш вопрос:

    • Да, это вполне возможно.
    • Вы, вероятно, не должны это делать.

    Как это сделать

    Это прекрасно, если вам нужно только реально поддерживать действительно (действительно реально) новые браузеры через Proxy API .

     var realObject = { foo: function(){ alert("Bar"); }); // our fooable api var api = new Proxy({}, { get: function(target, name){ if(name in target){ // normal API call return target[name]; } // return whatever you want instead of the method: return function(){ alert("Baz"); }); } }); api.foo(); //alerts Bar api.bar(); //alerts Baz api.IWillNotBuyThisRecordItIsScratched(); // alerts Baz 

    Таким образом, хотя поддержка браузера очень трясается,

    Почему вы не должны

    Интерфейсы передают поведение, выше таких случаев, как опечатки, которые могут (и должны) быть обычно пойманы статическими инструментами анализа, такими как jshint или ternjs.

    Проверка инструментов для опечаток просто недостаточно мощна, чтобы передать поведение в JavaScript, проверка типов считается анти-шаблоном, как правило – на таких языках, как JavaScript, Ruby и Python, вы знаете типы, которые вы получите.

    Если вы работаете со строго определенными объектами, вы должны использовать пользовательские объекты вместо объектных литералов:

     function Foo(bar, baz) { this.bar = bar; this.baz = baz; } Foo.prototype = { fizz: function () { alert(this.bar + ' ' + this.baz + '!'); } }; //elsewhere f = new Foo('Hello', 'World'); f.fizz(); в function Foo(bar, baz) { this.bar = bar; this.baz = baz; } Foo.prototype = { fizz: function () { alert(this.bar + ' ' + this.baz + '!'); } }; //elsewhere f = new Foo('Hello', 'World'); f.fizz(); 

    И затем вы можете определить, является ли объект экземпляром Foo , используя оператор instanceof :

     function Buzz(foo) { if (foo instanceof Foo) { foo.fizz(); } } f = new Foo('Hello', 'World'); Buzz(f); 

    Если вы просто хотите проверить, содержит ли объект функцию по определенному параметру, вы можете использовать что-то вроде:

     function hasFunction(obj, param) { return (typeof obj[param] === 'function'); } o = { foo: function () {} } hasFunction(o, 'foo'); //true hasFunction(o, 'bar'); //false 

    Сегодня это не очень полезно (благодаря поддержке пятнистого браузера), но Proxy API позволит вам писать код, который перехватывает доступ к объектам на объекте. Другими словами, когда вы пишете:

     obj.foo(); 

    Ловушка прокси-сервера может затем вернуть все, что захочет (для вызова), независимо от того, действительно ли свойство существует на исходном объекте.

    Interesting Posts

    Имя переменной, добавляемое вместо значения, javascript

    Mongoose.js: Найти пользователя по имени пользователя LIKE value

    Как опубликовать сценарий Greasemonkey в качестве дополнения к Firefox?

    Jquery ajax и java-сервер, потерянные данные

    JavaScript: использование конструктора без оператора 'new'

    Почему вызов jQuery's appendChild завершается с неопределенной ошибкой?

    Чтение и запись в базу данных доступа с использованием Javascript

    Как применить стиль CSS ко всем элементам с одинаковым идентификатором с помощью одной кнопки?

    Условно задано свойство объекта JSON

    Добавить href в ссылки динамически

    Ожидание загрузки изображения в Javascript

    Match () возвращает массив с двумя совпадениями, когда я ожидаю одного совпадения

    Добавить общую серию в легенду в Highcharts

    Исключение полей формы из обработчика нажатия клавиш, назначенного телу

    Является ли componentDidMount родительского имени после всех компонентных дочерних элементов?

    JavaScript делает сайт умным, красочным и простым использованием.