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

kidar2 28.01.2011 13:59

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

sysif 28.01.2011 14:12

Знание о том, наличие каких функций надо проверять, где будет сосредоточено?

kidar2 28.01.2011 14:16

Сосредоточить в таком виде

function IDisposable()
{
this.Dispose = function() {};
}

function isImplemented(classType, interfaceType)
{
// и тут бегаем по членам interfaceType проверяя есть ли они в classType
}

sysif 28.01.2011 14:31

Понятно, т.е. отдельный объект под "интерфейс". Кстати, а сигнатуры методов проверятся будут? Если да, то как?

Kolyaj 28.01.2011 14:37

Цитата:

Сообщение от sysif
а сигнатуры методов проверятся будут?

Сигнатур методов в JS тоже нет. Любая функция может принимать любое количество аргументов любых типов и возвращать значение любого типа.

sysif 28.01.2011 14:49

Цитата:

Сообщение от Kolyaj (Сообщение 90206)
Сигнатур методов в JS тоже нет.

Понятно, но соглашения-то какие-то, по кол-ву аргументов, например, можно было бы ввести? Если уж мы таки пришли к реализации "интерфейсов". Вот я и уточняю

Kolyaj 28.01.2011 14:56

Цитата:

Сообщение от sysif
Если уж мы таки пришли к реализации "интерфейсов".

Мы не пришли к реализации "интерфейсов". Лично я пытаюсь максимально увести вас от них :)

B~Vladi 28.01.2011 15:16

Ставлю на Kolyaj!:yes:

with-love-from-siberia 28.01.2011 15:36

B~Vladi,
давайте подождем. Так хочется увидеть реализацию интерфейсов в js (-:

sysif 28.01.2011 15:59

Цитата:

Сообщение от Kolyaj (Сообщение 90211)
Мы не пришли к реализации "интерфейсов".

Пришли к обсуждению их реализации. Не придирайтесь к словам

Цитата:

Сообщение от Kolyaj (Сообщение 90211)
Лично я пытаюсь максимально увести вас от них :)

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

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())
}

EmperioAf 23.07.2015 16:33

Цитата:

Сообщение от tysonfury2015
подобный подход, с предварительными объявлениями, оправдывает себя лишь в одном случае, при построении цепочек наследования с использованием оператора with.

Использования with, который по сути deprecated ничего не оправдывает (http://javascript.ru/with)

tysonfury2015 23.07.2015 16:38

EmperioAf,
Во первых, речь шла не о with как таковом, а об использовании предварительных деклараций, я тебе показал, где оно имеет смысл. Кроме этого случая, это нигде смысла не имеет, в том числе и в бредокоде, который тут выложен выше.

По поводу with. Меня не интересует, что какой-нибудь очередной вася пупкин думает по поводу его использования. Он есть в стандарте, в том числе в ES6

Erolast 23.07.2015 16:39

Цитата:

есть в стандарте, в том числе в ES6
В модулях ES6 with запрещен (там форсится строгий режим).

tysonfury2015 23.07.2015 16:43

Цитата:

Сообщение от Erolast
В модулях ES6 with запрещен

Ну так не пиши в модулях, ты чо дебил штоли?

titulus 02.11.2016 21:24

специально для вас
 
Цитата:

Сообщение от kidar2 (Сообщение 89569)
Мне вот хотя бы один пример велосипеда с интерфейсами посмотреть...

держи мой велосипед:

jsInterface - реализация идеи классических ООП интерфейсов с поправкой на динамическую природу JavaScript.
https://github.com/titulus/js-interface


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