Как защитить функции, которые вызываются в разных контекстах, от взлома?
Я довольно новичок в javascript, и теперь я узнал, как работает вызов функций с контекстом.
Вот простой пример, который ставит вопрос в моей голове. Допустим, у нас есть этот пример:
var myObj = {
bar: function() {
console.log("Lets got to the bar!");
}
}
/* how can this be protected from errors,
* if a passed object doesn't contain bar */
function foo()
{
this.bar();
}
foo.call(myObj);
Теперь, как можно защитить foo от взлома? В некотором языке ООП (скажем, Java) это будет реализовано, скажем, через интерфейс. Таким образом, в этом случае, если объект, который создается, не реализовал интерфейсный метод, компилятор из-за ошибки, так что компилятор защищает код / программу от ошибок (в этом случае, конечно).
public interface MyInterface
{
public void bar();
}
public class MyClass implements MyInterface
{
public void bar()
{
System.println("Lets go to the bar");
}
}
MyInterface m = new MyClass();
m.bar(); // if bar isn't implemented the compiler would warn/break
Примечание: я не очень хорош в Java, поэтому прошу прощения за любой синтаксис или другие ошибки, но я надеюсь, что вы поняли.
Подводя итог, я вижу, что в обоих случаях в обоих языках можно достичь полиморфизма, верно? Теперь, если так для примера Javascript, как можно защитить его от взлома, есть ли какие-то шаблоны или уловки? Есть ли typeof this.bar === function
Работа? Если так, кто гарантирует качество ПО, если программист забывает об этом, я задаю такой вопрос, потому что у Java есть компилятор, чтобы предупредить программиста об ошибке, есть ли в JS что-то похожее, какой-то инструмент проверки качества?
2 ответа
Javascript - это динамический * интерпретируемый язык. Нет шага компилятора для проверки ссылок. Некоторые инструменты (jsline) и IDE (VS, Webstorm) могут выполнять некоторые проверки во время разработки, но в действительности нет безопасности типов. Это в основном рассматривается как функция, а не ошибка.
Есть множество хитростей, чтобы обойти это (.hasOwnProperty, typeof x === 'function', хранение собственных ссылок, привязка контекста), но в основном, если вы хотите безопасность типов, вам нужен другой язык.
Моя рекомендация - Typescript. Он имеет Java/C-подобный синтаксис, с некоторыми знакомыми функциями ООП, такими как классы, интерфейс (и, следовательно, здравый полиморфизм) и универсальные типы, и мгновенно переносится в javascript.
Если вы используете конструктор для создания своего объекта, вы можете использовать встроенные в Javascript функции проверки членства в классе. Пример ниже.
class MyClass {
bar() { console.log("Lets got to the bar!")}
}
function foo() {
if ( this instanceof MyClass ) {
this.bar();
}
else {
console.log('this is not a member of the MyClass');
}
}
foo.call(new MyClass);
Имейте в виду, что проверка типов в Javascript ужасно ненадежна, и вам, вероятно, не следует ее использовать. Если ваш объект содержит в своей цепочке прототипов тот же прототип, что и класс, в котором вы тестируете его на членство, instanceof вернет true.
Пример быстрой и грязной печати утки
Это выкинет, если вы дадите ему объект без свойств, которые вы проверяете, но вы поняли идею.
class MyClass {
constructor() {
this.feathers = 'white';
this.feet = 'webbed';
}
bar() { console.log("Lets got to the bar!")}
}
function foo() {
if (
this.hasOwnProperty('feathers') &&
this.hasOwnProperty('feet') &&
this.feathers === 'white' &&
this.feet === 'webbed'
)
{
this.bar();
}
else {
console.log('this is not a member of the MyClass');
}
}
foo.call(new MyClass);