Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Интерфейсы в javascript (https://javascript.ru/forum/misc/14657-interfejjsy-v-javascript.html)

Kolyaj 28.01.2011 16:04

Цитата:

Сообщение от sysif
Потому что бесполезно или потому что вредно? Агрументируйте, плиз

Извините, я не смогу вам аргументировать, вы не поймёте. Вы пришли из статического языка и пытаетесь писать на JavaScript так, как вы писали на другом языке. Ничего хорошего из этого получится не может.

Читайте чужой код на JavaScript. Посмотрите как реализованы известные фреймворки, ExtJS, например. JQuery не смотрите, там чёрт ногу сломит.

x-yuri 29.01.2011 04:30

Цитата:

Сообщение от sysif
Может быть, вы тогда с такой же уверенностью скажете, зачем в языке с динамической типизацией конструкции instanceOf и typeof ?

да, надо признать, так уверенно я уже сказать не смогу :) не подумал об этом моменте. Но тогда я не вижу другого применения интерфейсам, кроме как в глобально-архитектурных задачах, необходимость решения которых не доказана

Цитата:

Сообщение от sysif
Аргументы в пользу я так понимаю были отброшены как не значимые?

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

но если вы знаете задачи, в которых нужны интерфейсы (в контексте js)... я всегда открыт для новых знаний ;)

x-yuri 29.01.2011 05:04

а про typeof мне приходит в голову только выполнение разных действий в зависимости от типа аргументов
function $( id ){
    return   typeof id == 'string'   ? document.getElementById(id)   : id;
}


в конце концов присутствие чего-либо в языке ничего не означает. Вспомнить хотя бы The Good Parts Дугласа Крокфорда

with-love-from-siberia 30.01.2011 16:52

Цитата:

Может быть, вы тогда с такой же уверенностью скажете, зачем в языке с динамической типизацией конструкции instanceOf и typeof ?
Так как js - язык слабо типизированный, то необходим инструмент для определения типа конкретного объекта. Для этих целей и существуют операторы typeof и instanceof.

Первый оператор позволяет отличить примитивные типы от объектов. Второй - чтобы отличить один тип объекта от другого.

Этого достаточно, чтобы работать с языком, использовать всю его мощь и не думать об интерфейсах. Есть некоторые "казусы", о которых надо просто помнить. Например:
Код:

typeof null == 'object'
typeof [] == 'object'


with-love-from-siberia 30.01.2011 17:27

kidar2,
sysif,
Решает ли этот код проблему отсутствия интерфейсов?

Источник - http://javascript.ru/forum/66098-post2.html
Object.mixin = function(dst /*, arg1, arg2... */)
{
	for (var i = 1; i < arguments.length; i++) {
		for (var prop in arguments[i]) {
			if ( arguments[i].hasOwnProperty(prop) ) {
				dst[prop] = arguments[i][prop];
			}
		}
	}
	return dst;
}

Function.prototype.inherit = function(proto)
{
	var that = this;
	proto = proto || {};
	var constructor = proto.hasOwnProperty('constructor') ? proto.constructor : function() { that.apply(this, arguments); };
	var F = function() {};
	F.prototype = this.prototype;

	// Оригинальная строка источника
	//constructor.prototype = mixin(new F(), proto);

	var dst = Object.mixin(new F(), proto);

	for (var i = 1; i < arguments.length; i++) {
		if ( ! arguments[i] ) {
			continue;
		}
		for (var p in arguments[i].prototype) {
			if ( ! arguments[i].prototype.hasOwnProperty(p) ) {
				continue;
			}
			if ( typeof arguments[i].prototype[p] == 'function' && typeof dst[p] != 'function' ) {
				throw new ReferenceError('"' + p + '" method is not implemented');
			}
		}
	}

	constructor.prototype = dst;

	constructor.superclass = this.prototype;
	constructor.prototype.constructor = constructor;
	return constructor;
};

// Глобальный интерфейс - родитель всех остальных интерфейсов
var Interface = Object.inherit({
	constructor: function()
	{
		throw new ReferenceError('An object could not be instantiated from an interface');
	}
});

// Интерфейс - Перемещаемые объекты
var IMovable = Interface.inherit({
	move: function() {}
});

// интерфейс - Рисуемые объекты
var IDrawable = Interface.inherit({
	draw: function() {}
});

// Класс Точка
// реализует интерфейсы Перемещаемые, Рисуемые
// но не реализует все методы интерфейсов
// поэтому будет брошено исключение
var Point = Object.inherit({
	constructor: function(x, y)
	{
		this.x = x;
		this.y = y;
	}, 
	draw: function()
	{
		alert('Point at [' + this.x + ', ' + this.y + ']');
	}
}, IMovable, IDrawable);

// Этот код не будет выполнен пока 
// 1. не будет реализован метод "move" или 
// 2. не будет исключен интерфейс Перемещаемые из цепочки наследования
var obj = new Point(1, 1);
obj.draw();

monolithed 30.01.2011 23:10

а что, действительно похоже, объемно только...;)

Gaito 23.07.2015 10:22

Какая старая статья... И всё же хочется кое-что сказать.
Во-первых JavaScript не класс-ориентированный язык программирования а прототипный (что это значит можно почитать на вики) и соответственно практики из класс-ориентированного ООП в принципе не совсем для него подходят, хотя если вам нужен некий аналог интерфейса, то могу предложить следующее решение:

// интерфейс
var interfaceA = {
  methodA: methodForMatchAPlusB,
  methodB: methodForMatchAMinusB,
  methodC: methodC
};

// основной код
console.info('a + b = %d', interfaceA.methodA(1, 2));
console.info('a - b = %d', interfaceA.methodB(7, 5));
interfaceA.methodC(7, 4);

//объявление функций
function methodForMatchAPlusB(a, b) {
  return a+b;
}

function methodForMatchAMinusB(a, b) {
  return a - b;
}

function methodC(a, b) {
  var result = interfaceA.methodA(a, b) * interfaceA.methodB(a, b);
  console.info('(a+b)*(a-b) = %d', result);
}


Или можно тоже самое оформить ещё лучше:

var objectA = new function() {
  // интерфейс
  this.methodA = methodForMatchAPlusB;
  this.methodB = methodForMatchAMinusB;
  this.methodC = methodC;


  //объявление функций
  function methodForMatchAPlusB(a, b) {
    return a+b;
  }

  function methodForMatchAMinusB(a, b) {
    return a - b;
  }

  function methodC(a, b) {
    var result = objectA.methodA(a, b) * objectA.methodB(a, b);
    console.info('(a+b)*(a-b) = %d', result);
  }
};


// основной код (возможно уже в другом файле)
console.info('a + b = %d', objectA.methodA(1, 2));
console.info('a - b = %d', objectA.methodB(7, 5));
objectA.methodC(7, 4);

tysonfury2015 23.07.2015 11:29

Цитата:

Сообщение от with-love-from-siberia
Решает ли этот код проблему отсутствия интерфейсов?

В чем заключается "проблема" отсутствия ынтырфейсов? Покажи задачу, которую с ынтырфейсами решить проще или эффективней, чем без них.

tysonfury2015 23.07.2015 11:34

Цитата:

Сообщение от Gaito
Или можно тоже самое оформить ещё лучше:

Твой код не имеет ни малейщего смысла, с точки зрения семантики. Ты просто размазал какие-то непонятные сопли. Это то же самое, примерно, что
fu1=function(){}
fu2=function(){}
ob={a: fu1, b: fu2}

tysonfury2015 23.07.2015 11:53

Gaito, подобный подход, с предварительными объявлениями, оправдывает себя лишь в одном случае, при построении цепочек наследования с использованием оператора with.
Operations={
  data: "",
  sum: "",
  mul: "",
  combine: function(){with(this) return sum()+mul()}
}

with(OperationsWithArray=Object.create(Operations)){
  sum=function(){return this.data.reduce(function(x, y) {return x + y})}
  mul=function(){return this.data.reduce(function(x, y) {return x * y})}
}

with(OperationsWithNumber=Object.create(Operations)){
 sum=function(){return this.data+this.data}
 mul=function(){return this.data*this.data}
}

with(Object.create(OperationsWithArray)){
 data=[1,2,3]
 console.log(combine())
}

with(Object.create(OperationsWithNumber)){
 data=3
 console.log(combine())
}


Часовой пояс GMT +3, время: 19:36.