Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Добавление методов к стандартным объектам и совместимость кода (https://javascript.ru/forum/misc/10717-dobavlenie-metodov-k-standartnym-obektam-i-sovmestimost-koda.html)

Василий Б. 17.07.2010 13:05

Добавление методов к стандартным объектам и совместимость кода
 
Приветствую всех.

Во-первых, интересует вопрос, как правильно писать собственные библиотеки кода? По каким правилам, как делать пространство имен и т.д.?

Второй конкретный вопрос:

У меня имеется собственная библиотека кода, сейчас задумался, насколько правильно я её писал.

Суть дела вот в чем: в библиотеке я расширял стандартные объекты языка, например:

Array.prototype.in_array = function(arg)
{
    for (var i=0; i < this.length; i++)
    {
		if (this[i] == arg)
        {
		    return i;
		}
	}

	return -1;
}


у меня есть подозрение, что так писать не правильно, ибо в случае перебора массива

var a = new Array('element', 'element2');

for (j in a)
{
	alert(a[j] + ' is ' + typeof a[j]);
}


последний элемент массива будет элемент a[j] будет моим методом in_array. Это может сказаться на совместимости с другими сторонними кодами, верно?

exec 17.07.2010 13:24

Используйте hasOwnProperty.

Octane 17.07.2010 13:35

for-in для array использовать не принято.

x-yuri 17.07.2010 17:28

расширять DOM опаснее

пространство имен можно создать так
var MyNamespace = {
    func1: function(){...}
    ...
};

можно создать область видимости, к содержимому которой нельзя будет получить доступ извне и которая влияет на глобальную область видимости ровно настолько насколько это необходимо
(function(){
    var privateVariable = ...;
    window.MyNamespace = {}; // или this.MyNamespace = {}; или MyNamespace = {};
    window.MyNamespace.func1 = ...;
})();

а вообще, первый вопрос слишком нечеткий. Посмотри, как другие фреймворки сделаны или спроси что-нибудь по-конкретнее

Kolyaj 19.07.2010 12:29

Цитата:

Сообщение от Василий Б.
Array.prototype.in_array

Судя по коду, это не in_array, а indexOf, который, кстати, реализован во всех браузерах кроме IE, но немного по другому.

Цитата:

Сообщение от Василий Б.
ибо в случае перебора массива

В своей же функции вы не перебираете массив циклом for-in. И в других не надо.

Цитата:

Сообщение от Василий Б.
Это может сказаться на совместимости с другими сторонними кодами, верно?

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

x-yuri 19.07.2010 21:11

Цитата:

Сообщение от Kolyaj
Некоторые даже популярные фреймворки реализованы тупо неправильно

интересно, а можно примеры?

Василий Б. 19.07.2010 22:07

Хорошо.

Я тут поглядел на некоторые популярные фреймворки, как они абстрагируются от всего остального:

var Prototype = {
...

(function( window, undefined ) {
... 
})(window);


я так понимаю, они существуют в глобальной области, Prototype как объект, а jQuey как метод объекта window?

x-yuri 19.07.2010 23:17

где-то так, только граница не такая четкая. Глобальные переменные - свойства объекта window, причем переменная может содержать любое значение, например, функцию. Но функция - это тоже объект
alert(Function instanceof Object);

и значение. Например, можно присвоить функцию переменной
var s = '...';
var f = function(){...};

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

т.е. я бы сказал, что jQuery ($) это просто глобальная функция

по поводу фреймворков, основные подходы следующие:
1) объект-обертка, доступ к функционалу осуществляется через временный объект: $('a').click(function(){...})
2) расширение DOM/встроенных объектов: Array.prototype.method = function(){}
3) отдельные "классы"

по поводу областей видимости, можно сказать, что jQuery создает свою область видимости, потому что все манипуляции осуществляются через временный объект. mootools, prototype свои "классы" никак не изолируют от глобального пространства имен

Kolyaj 20.07.2010 09:28

Цитата:

Сообщение от x-yuri
интересно, а можно примеры?

Prototype.js
var a = [1,,,,2], values = '';
a.each(function(value) {
    values += value;
});
alert(values); // В IE 1undefinedundefinedundefined2
               // В остальных браузерах 12


var a = [];
a[5] = undefined;
alert(a.indexOf(undefined));  // IE -- 0, остальные браузеры -- 5



Цитата:

Сообщение от x-yuri
alert(Function instanceof Object);

Как-то случайно пример заработал. С тем же успехом
alert(String instanceof Function);

x-yuri 20.07.2010 11:55

Цитата:

Сообщение от Kolyaj
Как-то случайно пример заработал

это был пример показывающий всю суть... :) вообще-то я имел в виду
alert( function(){} instanceof Object );


Цитата:

Сообщение от Kolyaj
Некоторые даже популярные фреймворки реализованы тупо неправильно

А, я думал ты про какие-то недостатки архитектурного (что ли) плана


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