Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   имя метода оказывается в списке элементов хэша (https://javascript.ru/forum/misc/26892-imya-metoda-okazyvaetsya-v-spiske-ehlementov-khehsha.html)

x15nicky 26.03.2012 18:32

имя метода оказывается в списке элементов хэша
 
задумал я сделать такую функцию:
{a:1, b:2, s:3}.k_string() => 'a=1 b=2 c=3'
(чтоб группировать куки по темам).

и вот, что вышло:
Object.prototype.k_string = function()
{
	var res = '';
	var odd = 1;
	for(var next in this)
	{
		res += next+'='+this[next]+' ';
	}
	return res;
};

var h = {a:1, b:2, s:3};
console.log(h);
console.log(h.k_string());


в консоле наблюдаем:
Object 
a 1
b 2
s 3
Object
ifube.js:33
a=1 b=2 s=3 k_string=function()
{
	var res = '';
	var odd = 1;
	for(var next in this)
	{
		res += next+'='+this[next]+' ';
	}
	return res;
}


то есть метод k_string(), которым я расширил Object оказался в списке свойств объекта.

подскажите плиз, с чего бы это и как с ним бороться?

сенки.

monolithed 26.03.2012 18:54

Цитата:

Сообщение от x15nicky
подскажите плиз, с чего бы это и как с ним бороться?

Как минимум, переписать нормально код, без расширения базового типа.
Про остальные варианты вам лучше пока не знать :)

x15nicky 26.03.2012 19:09

да, я пробовал расширить Hash:
Uncaught exception: ReferenceError: Undefined variable: Hash

Error thrown at line 20, column 0 in [url]http://ifube.us/js/ifube.js?v=0.06:[/url]
    Hash.prototype.k_string = function()


я конечно, далеко не гуру в JS, но мне кажется, что функциональность хэша = как раз базовая функциональноть Object-a

nasqad - хотелось бы сделать вариант, который не накладывал бы ограничений на значение ключа.

Раед 26.03.2012 20:37

Вот вроде рабочий вариант
Object.prototype.k_string = function()
{
    var res = '';
    var odd = 1;
    for(var next in this)
    {
        *!*if (!this.hasOwnProperty(next)) continue;*/!*
        res += next+'='+this[next]+' ';
    }
    return res;
};
 
var h = {a:1, b:2, s:3};
console.log(h);
console.log(h.k_string());

x15nicky 27.03.2012 11:35

работает, спасибо, заценил.

правда, оказалась такая досада - если в хеше есть элемент с индексом k_string (да хоть toString), то соответствующая функция оказывается недоступной.

с одной стороны - понятно, может существовать только один элемент с определенным ключом, но с другой - обращения к ним разные
h.toString - поле
h.toString() - функция

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

кстати, правильный объект я тут расширяю, или для хеша есть что-либо более специфическое?

x15nicky 27.03.2012 14:10

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

например вполне уважаемый Jqgrid получив хеш с параметрами, проверяет их на допустимость и ругается, увидев лишний. (хуже того - мрёт).

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

Aetae 27.03.2012 15:05

monolithed, в самом начале всё правильно сказал.
А набижавшие после человеки вам зла хотят, точно вам говорю.

x15nicky 27.03.2012 15:43

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

monolithed 28.03.2012 12:59

Цитата:

Сообщение от x15nicky
и никаких намеков на то что можно было бы погуглить не воспоследовало

Интересно, что вам я вам должен был в этом случае посоветовать? Что такое функция или почему крайне не желательно без особых на то причин расширять расширять базовые типы и с чего вы вообще взяли что так принято делать без особых на то причин?
Цитата:

Сообщение от x15nicky
не говоря уже о том, чтоб привести правильный код.

Вот моя реализация функция print_r() вероятно она вам нужна

x15nicky 28.03.2012 17:39

понятно, что не надо расширять базовый тип. НО, когда я отправляю в консоль {} она печатает Object:
Цитата:

Object
Object
__defineGetter__ Function
__defineSetter__ Function
__lookupGetter__ Function
__lookupSetter__ Function
constructor Function
hasOwnProperty Function
isPrototypeOf Function
k_string Function
propertyIsEnumerable Function
toLocaleString Function
toString Function
valueOf Function
это, вкупе с тем фактом, что класс Hash не существует, см. коммент
навело меня на мысль что хеш и есть Object. если Вы обладаете сакральным знанием о том, какой объект надо расширить, чтоб добавить метод в хеш, то тут самое место им поделиться. отмечу, что я об этом повторно спрашивал и ответа не получил (в гугле тоже искал).


Цитата:

Сообщение от monolithed
Вот моя реализация функция print_r() вероятно она вам нужна

нет, мне нужна функция, которая делает строго это:
Цитата:

{a:1, b:2, s:3}.k_string() => 'a=1 b=2 c=3'
и более того, хотелось бы сделать ее методом хеша и так, чтоб элемент хеша с одноименным ключом не делал бы этот метод (равно как и любой другой) недоступным. (с самой функцией, собственно, проблем нет.)

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

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

monolithed 28.03.2012 19:01

var object = {
    a: 1,
    b: 2, 
    c: {
        d: 3
    }
};

Object.defineProperty(Object.prototype, 'dump', {
    value : function() {
        var output = [];
		
		for (var i in this) {
			if (this.hasOwnProperty(i)) 
			{
				var key = i + "=";
				var value = this[i];
				
				output.push(key += {
				   "[object Object]" : value.dump(),
				   "[string Object]" : "\"" + value + "\""
				}[Object.prototype.toString.call(value)] || value);
			}
		}
		return "{" + output.join() + "}";
	},
    configurable: 1,
	writable : 0,
    enumerable: 0
});

alert(object.dump());

x15nicky 28.03.2012 20:06

за код - спасибо. про defineProperty по крайней мере - не знал.

но не знаю, мож я плохо объясняю. у меня нет проблем с функцией, которая делает это:
Цитата:

{a:1, b:2, s:3}.k_string() => 'a=1 b=2 c=3'
там 6 строчек, включая скобки. вложенных массивов в моем конкретном случае не будет.

проблема, повторю еще раз, в том, что, похоже, что нет возможности использовать одновременно ключ хеша и одноименную функцию:
console.log({a:1, b:2, dump: 3}.dump());

Цитата:

Uncaught exception: TypeError: '{a:1, b:2, dump: 3}.dump' is not a function

Error thrown at line 54, column 0 in http://ifube.us/js/ifube.js?v=0.06:
console.log({a:1, b:2, dump: 3}.dump());
и эта проблема - как видите, осталась, как бы ни был прекрасен (без иронии говорю) джаваскрипт в остальном. это относится, кстати и к встроенным функциям, типа toString.

Aetae 28.03.2012 21:13

Это нихрена не баг, а вполне себе фича.)

Раед 28.03.2012 21:24

x15nicky,
Да вы язык кажется не понимаете, функция - это тоже переменная, поэтому нельзя создать одноимённы метод и свойство.

x15nicky 28.03.2012 21:28

я это понимаю, и об этом писал выше. но всеж в PHP нет ограничений на имена ключей. в Руби - тоже. и если эта фича будет ликвидированна в будущих версиях, я думаю, никто о ней не пожалеет.

кто-то из вас, господа гуру мне минусанул карму на 8 сотен. я на вашем месте счел бы в такой ситуации за честь ее вернуть.

Цитата:

Сообщение от monolithed
Как минимум, переписать нормально код, без расширения базового типа.{

Цитата:

Сообщение от x15nicky
в особенности буду рад услышать, как же все-таки называется класс, который следует расширять вместо базового.

Цитата:

Сообщение от monolithed
Object.defineProperty(Object.prototype, 'dump', {


monolithed 28.03.2012 23:07

Одноименное свойство можно только в прототип добавить:
var object = {
    a: 1
};

object.__proto__.a = 2;
alert([object.a, object.__proto__.a]);

Kolyaj 30.03.2012 01:06

Нет никаких хэшей в JavaScript-е, есть объекты, которые иногда называют хэшами, но это одно и то же.

Цитата:

Сообщение от x15nicky
но всеж в PHP нет ограничений на имена ключей. в Руби - тоже.

В JavaScript-е тоже нет ограничений на имена ключей.

Раед 08.04.2012 00:27

Цитата:

Сообщение от x15nicky
но всеж в PHP нет ограничений на имена ключей. в Руби - тоже. и если эта фича будет ликвидированна в будущих версиях, я думаю, никто о ней не пожалеет

Я пожалею. И ещё, думаю, 95% js программистов

p.s. это не фича, а особенность языка


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