Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Помогите с созданием нового объекта (https://javascript.ru/forum/misc/20897-pomogite-s-sozdaniem-novogo-obekta.html)

yambbkru 22.08.2011 01:49

Помогите с созданием нового объекта
 
Помогите начинающему веб-программисту разобраться с ООП. Я хочу создать объект, который что-то делает с блоком <div>, например вставляет туда кнопку при нажатии на которую еще что-то делается ЭТИМ же объектом. Я имею ввиду, что объект внутри блока <div id="DivId"> создается код html с кнопкой, у которой событие - это метод этого же объекта. Что-то типа такого:
function myObj() {
  this.a = "Text";
  this.func1 = function() {
    $("#DivId").html('<input type="button" value="' + this.a + '" onclick="' + this.func2 + '">');
  }
  this.func2 = function() {alert("Ok")}
  this.func1();
}

$().ready(function() {var myBut = new myObj(); });

Как это вообще реализовать? Как правильно задать событие кнопке? Ведь когда эта кнопка присоединиться к дереву, то это уже должно быть как бы обращение к методу funk2 из вне объекта.

Octane 22.08.2011 05:27

Начинающему программисту лучше пока оставить jQuery в покое и начать читать:
http://dmitrysoshnikov.com/ecmascrip...eneral-theory/
http://dmitrysoshnikov.com/ecmascrip...mplementation/
ну и остальные статьи там и на этом сайте.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>…</title>
</head>
<body>
<div id="test-container"></div>
<script>
if (!Function.prototype.bind) {
	Function.prototype.bind = function (obj) {
		var args = Array.prototype.slice.call(arguments, 1), thisFunc = this;
		function wrap() {
			return thisFunc.apply(this instanceof wrap ? this : obj || window, args.concat(Array.prototype.slice.call(arguments)));    
		}
		return wrap;
	};
}

var common = {
	event: {
		add: function (element, eventType, listener) {
			var wrap;
			if ("addEventListener" in element) {
				element.addEventListener(eventType, listener, false);
			}
			else if ("attachEvent" in element) {
				wrap = function () {
					listener.call(element, window.event);
				}
				element.attachEvent("on" + eventType, wrap);
			}
			return wrap || listener;
		}
	}
};

function MyObj(node) {
	this._container = node;
	this.render();
}

MyObj.prototype = {

	constructor: MyObj,

	buttonCaption: "Text",
	message: "Ok",
	eventType: "click",

	_container: null,
	_button: null,

	render: function () {
		this.addButton();
		this.initEvents();
	},

	addButton: function () {
		var btn = document.createElement("input");
		btn.type = "button";
		btn.value = this.buttonCaption;
		this._container.appendChild(btn);
		this._button = btn;
	},

	initEvents: function () {
		common.event.add(this._button, this.eventType, this.showMessage.bind(this));
	},

	showMessage: function () {
		alert(this.message);
	}
};

new MyObj(document.getElementById("test-container"));

</script>
</body>
</html>

popov654 22.08.2011 09:43

Ну Вы жжёте вообще) Я весь мозг сломал пока процентов 20 отсюда понял :)

Андрей38 22.08.2011 10:47

Я плагин видел для Квери,создающий новый объект. Погуглите,найдете его

Octane 22.08.2011 11:20

jQuery головного мозга детектед

popov654 22.08.2011 11:55

У кого?))

Kolyaj 22.08.2011 12:26

Цитата:

Сообщение от Андрей38
Я плагин видел для Квери,создающий новый объект. Погуглите,найдете его

Универсальный ответ на любой вопрос: Я плагин видел для Квери, делающий название темы. Погуглите,найдете его.

SkyLight 22.08.2011 12:34

popov654, вам бы действительно для начала основы подучить. Чего вы хотите добиться этой строкой:
onclick="' + this.func2 + '"

Вот как думаете, что у вас туда попадет?

Octane 22.08.2011 13:08

Цитата:

Сообщение от popov654
У кого?))

у Андрей38

Цитата:

Сообщение от SkyLight
popov654, вам бы действительно…

тему создал yambbkru

yambbkru 22.08.2011 14:02

Спасибо за ссылки, но подобную литературу я уже прочла. Но вот несколько моментов осталось непонятых. Я изучила основы JavaScript jQuery, по только ОСНОВЫ. Я могу написать на JavaScript процедурным способом. Т. е. создать 20 функций в скрипте и вызывать из одной функции другую. Так у меня получается. Но я хочу разобраться с ООП, с пространством имен. Мне нужна помощь конкретно в этом примере. Еще раз привожу его, немного изменив. Вот есть страничка index.php
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
		<script type="text/javascript">	
			var first = "Первая кнопка",
				second = "Вторая кнопка";			
			function firstBut(){$("#doc").append('<input type="button" value="'+first+'" onclick="secondBut()">');}
			function secondBut() {$("#doc").append('<input type="button" value="'+second+'" onclick="ok()">');}
			function ok() {alert("ОК!");}		
			$().ready(function() {firstBut();});		
		</script>	
	</head>
	<body>
		Начало
		<div id="doc"></div>
	</body>
</html>

Если ее запустить, то все работает. Но тут реализовано процедурным способом. А как сделать так, что бы переменные first и second были свойвствами какого то объекта, а функции firstBut и secondBut - его методами?

yambbkru 22.08.2011 19:43

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

ILL-JAH 22.08.2011 20:56

yambbkru,
Создай объект, создай у объекта нужные свойства и методы.
А что должен делать скрипт?

yambbkru 22.08.2011 21:54

Да этот скрипт - выдуманный. Я его придумала только для того, что бы научится. Я вроде немного разобралась. Если я создаю объект вот так:
function C(a){with (C) {
				first = a.b;
				second = "Вторая кнопка";			
				firstBut = function() {$("#doc").append('<input type="button" value="'+first+'" onclick="secondBut()">');}
				secondBut = function() {$("#doc").append('<input type="button" value="'+second+'" onclick="ok()">');}
				ok = function() {alert("ОК!");}
				firstBut();
			}};
			$().ready(function() {new C({b:"Первая кнопка"});});

то, все работает так же, как и процедурным способом. Буду пока так делать...

ILL-JAH 22.08.2011 21:58

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

kadabrik 23.08.2011 00:30

Не самый удачный выбран пример. Как я понял нужно что-то типа этого:
function MyWTFObject()
{
  this.$obj = $('<div id="my-wtf-object" style="border:1px solid green"></div>').appendTo('body');
  this.$firstButton = new Object();
  this.$secondButton = new Object();
  this.createFirstButton();
}

MyWTFObject.prototype.createFirstButton = function()
{
  var obj = this;
  this.firstButton = $('<input type="button" value="first-button"/>')
                        .appendTo(this.$obj)
                        .click(function(){obj.createSecondButton()});
}

MyWTFObject.prototype.createSecondButton = function()
{
  var obj = this;
  this.firstButton = $('<input type="button" value="second-button"/>')
                        .appendTo(this.$obj)
                        .click(function(){obj.showOk()});
}

MyWTFObject.prototype.showOk = function()
{
  alert('ok');
}

/*----------------------------------------------*/
$(function()
{
  window.wtfObject = new MyWTFObject();
});

В примере используется ООП совместно с jQuery

yambbkru 26.08.2011 00:21

Я не очень поняла ваш пример! Вы можете дописать комментарии? Зачем использовать прототип? Почему просто нельзя добавить свойства и методы объекту?

yambbkru 26.08.2011 00:24

Для того, кто спрашивал что делает скрипт: мой выдуманный скрипт должен при запуске показывать кнопку, при нажатии на которую появляется еще одна кнопка, при нажатии на которую выскакивает сообщение ОК!

melky 26.08.2011 00:47

вот запускаемый скрипт - пример
<body> </body>

<script>
/* создает кнопку с указанным html и обработчиком клика  */
function Button( html, handler ){
    var a = document.createElement('button');
    a.innerHTML = html;
    a.onclick = handler;
    return a;
};

// когза страница загрузится, отобразим первую кнопку
window.onload = function(){

    // не знаю, зачем, но я их сохраняю
    var firstB,secondB;
    
    firstB = new Button("первая", function(){

        secondB = new Button("вторая", function(){
            alert("OK");
        });

        // добавляем её туда же,куда и первую
        firstB.parentNode.appendChild( secondB );
    });

    // добавляем первую кнопку в <body>
    document.body.appendChild( firstB );
};
</script>


это тот же код, но разноцветный.

/* создает кнопку с указанным html и обработчиком клика  */
function Button( html, handler ){
    var a = document.createElement('button');
    a.innerHTML = html;
    a.onclick = handler;
    return a;
};

// когза страница загрузится, отобразим первую кнопку
window.onload = function(){
    
    var firstB,secondB;
    
    firstB = new Button("первая", function(){
        secondB = new Button("вторая", function(){
            alert("OK");
        });
        // добавляем её туда же,куда и первую
        firstB.parentNode.appendChild( secondB );
    });
    // добавляемпервую кнопку в <body>
    document.body.appendChild( firstB );
};


использовать Button можно было и без new, но тут эти три буквы добавляют к читаемости кода

yambbkru 26.08.2011 01:16

Спасибо большое! Этот пример мне более понятен. Он больше похож на программирование в Делфи: каждая кнопка - объект и все они часть другого объекта - всего документа.

kadabrik 26.08.2011 01:32

Цитата:

Сообщение от yambbkru (Сообщение 122541)
Я не очень поняла ваш пример! Вы можете дописать комментарии?

//конструктор объекта-прототипа котрый будет всем рулить
function MyWTFObject()
{
  //создаем контейнер в который все будет отрисовываться
  this.$obj = $('<div id="my-wtf-object" style="border:1px solid green"></div>').appendTo('body');
  
  //объявим что у объекта есть два свойства - это первая и вторая кнопка соответственно
  this.$firstButton = new Object();
  this.$secondButton = new Object();
  
  //создадим первую кнопку
  this.createFirstButton();
}

//метод создает первую кнопку
MyWTFObject.prototype.createFirstButton = function()
{
  var obj = this;//переменная obj теперь ссылается на this который в данном контексте ссылается на сам объект (см замыкания)

  //создаем кнопку и сохраняем ссылку на нее в соответствующем свойстве объекта
  this.firstButton = $('<input type="button" value="first-button"/>')
                        .appendTo(this.$obj)//отрисовываем кнопку в контейнер
                        .click(function(){obj.createSecondButton()});//вешаем событие на клик по кнопке, так как указатель this в этом месте не ссылается на текущий объект то используем для доступа к текущему объекту ранее созданную переменную obj 
}

//метод создает вторую кнопку
MyWTFObject.prototype.createSecondButton = function()
{
  var obj = this;
  this.firstButton = $('<input type="button" value="second-button"/>')
                        .appendTo(this.$obj)
                        .click(function(){obj.showOk()});
}

//метод аллертует "ok"
MyWTFObject.prototype.showOk = function()
{
  alert('ok');
}

/*----------------------------------------------*/
$(function()
{
  //зоздаем экземпляр в глобальной области видимости(т.е. просто делаем его свойством window)
  window.wtfObject = new MyWTFObject();
});


Цитата:

Сообщение от yambbkru (Сообщение 122541)
Зачем использовать прототип? Почему просто нельзя добавить свойства и методы объекту?

Потому что это будет уже не ООП.

Sweet 26.08.2011 02:33

Абсолютно не понятно, зачем нужны эти строчки:
this.$firstButton = new Object(); 
this.$secondButton = new Object();
???

kadabrik 26.08.2011 09:51

Цитата:

Сообщение от Sweet (Сообщение 122568)
Абсолютно не понятно, зачем нужны эти строчки:
this.$firstButton = new Object(); 
this.$secondButton = new Object();
???

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

yambbkru 26.08.2011 22:16

Спасибо, kadabrik! Так стало понятней. А можно еще попутный вопрос? Я прочла уже несколько раз в учебнике и на этом сайте о наследовании в javascript. Но остались не понятые моменты. Допустим есть класс
function Obj1(c) {
this.a = c;
this.b = function() {alert(this.a);}
this.b();
}

При запуске
var myObj1 = new Obj1("1");

показывает сообщение 1. Теперь я хочу создать новый класс
function Obj2(c) {
this.d = c + [B]this.a[/B];
[B]this.b();[/B]
}

где this.a и this.b() - это свойство и метод объекта Obj1. Как мне связать эти эти объекты? Так?
Obj2.prototype = new Obj1("1")

Но тогда попутно создается и объект Obj1. Я читала про обходные пути, что мол создается объект, а функция-конструктор пустая или копируют свойства из первого объекта во второй...
А можно так связать объекты, что бы не создавать первый объект, а только взять его методы? Не скопировать, а как то сослаться не создавая его? Тем более строчка с прототипом должна быть написана вне обеих функций, я так поняла. Но было бы гораздо удобнее связать функции в теле второй функции Obj2. Так можно сделать? И еще вопрос. Что значит строчка
О1 = Obj1

? Как в этом случае ведут себя оба класса? Если в правый добавить свойства что будет? А если в левый? И что сделалось с прототипом?

kadabrik 26.08.2011 23:50

yambbkru, если речь идет о наследовании, то в js есть несколько способов его реализовать. Лично мне больше всего нравится этот метод. Для наследования именно свойств, а не методов лучше подходит вызов конструктора родителя в конструкторе потомка: MyClass.superclass.constructor.call(this). После этого все переменные объявленные в конструкторе родителя будут и у потомка.

melky 27.08.2011 00:02

Цитата:

Сообщение от yambbkru (Сообщение 122758)
есть класс
function Obj1(c) {
this.a = c;
this.b = function() {alert(this.a);}
this.b();
}

При запуске
var myObj1 = new Obj1("1");

я хочу создать новый класс
function Obj2(c) {
this.d = c + this.a;
this.b();
}

где this.a и this.b() - это свойство и метод объекта Obj1.

А можно так связать объекты, что бы не создавать первый объект, а только взять его методы?

Не скопировать, а как то сослаться не создавая его?

см. красную строку
function Obj1(c) {
    this.a = c;
    this.b = function() {
        alert(this.a);
    }
    this.b();
}
var myObj1 = new Obj1("1");

function Obj2(c) {
    debugger
    this.d = c + this.a;
    this.b();
}

*!*
Obj2.prototype = myObj1;
*/!*

// создадим экземпляр второго объекта, чтобы проверить работоспособность
new Obj2('c');


выдает два алерта, в которых 1.

Цитата:

Сообщение от yambbkru (Сообщение 122758)
О1 = Obj1

? Как в этом случае ведут себя оба класса? Если в правый добавить свойства что будет? А если в левый? И что сделалось с прототипом?

тут непонятно

kadabrik 27.08.2011 00:32

melky, как же всетаки текст на аватарке контрастирует с началом предыдущего сообщения :)

Андрей38 30.08.2011 18:00

Я увидел здесь разговор о var..Скажите пожайлуста, существет ли АНИМИРОВАНЫЙ АЛЕРТ и АНИМИРОВАНЫЙ var наподобие счетчика ? .Алерт выводит только стационарное значение var.
Причина вопроса такая_ меняется ширина картинки,ее анимированная ширина динамически передается другому объекту для его css.Как быть?

systemiv 30.08.2011 18:07

Цитата:

Сообщение от Андрей38
что-то такое наподобие счетчика,существует?

Да, замыкания

Андрей38 30.08.2011 18:08

Цитата:

Сообщение от systemiv (Сообщение 123584)
Да, замыкания

Спасибо!Буду юзать!

yambbkru 04.09.2011 23:32

А можно еще спросить? Вот есть такие 2 функции:
function a() {
  var t = {
    c : "1"
  }
  return t
}

function b() {
  var t = {
    d : "2"
  }
  return t
}

var A = a();
var B = b();
alert(A.c + B.d)

В результате выдает сообщение "12". Как мне сделать, что бы все объекты, создаваемые функцией b() имели своим прототипом объект, создаваемый функцией а()?

systemiv 05.09.2011 00:07

b.prototype = new a();

kadabrik 05.09.2011 00:31

Цитата:

Сообщение от systemiv (Сообщение 124831)
b.prototype = new a();

Не стоит злоупотреблять таким способом наследования. Тут создается совершенно лишний объект "a".

yambbkru 05.09.2011 10:02

А зачем там new? а() и b() - это функции, которые возвращают объекты. Это не конструкторы, я так понимаю. Объект создается внутри этих функций. Мне действительно не нужен лишний объект а!!! Я пока вижу только один способ наследования: копирование всех свойств из а() в b(). Но мне это не совсем нравится, поскольку лишнее время затрачивается на это копирование. Хотелось бы через прототип.

kadabrik 05.09.2011 10:59

Цитата:

Сообщение от yambbkru (Сообщение 124822)
А можно еще спросить? Вот есть такие 2 функции:
function a() {
  var t = {
    c : "1"
  }
  return t
}

function b() {
  var t = {
    d : "2"
  }
  return t
}

var A = a();
var B = b();
alert(A.c + B.d)

В результате выдает сообщение "12". Как мне сделать, что бы все объекты, создаваемые функцией b() имели своим прототипом объект, создаваемый функцией а()?

Если есть серьезное желание изучить javascript то не помешало бы изучить стиль написания кода на нем. Название объектов-прототипов должны начинаться с большой буквы, а все объекты которые строятся от них с маленькой, как и любые переменные.

Цитата:

Сообщение от yambbkru (Сообщение 124874)
А зачем там new? а() и b() - это функции, которые возвращают объекты. Это не конструкторы, я так понимаю. Объект создается внутри этих функций. Мне действительно не нужен лишний объект а!!! Я пока вижу только один способ наследования: копирование всех свойств из а() в b(). Но мне это не совсем нравится, поскольку лишнее время затрачивается на это копирование. Хотелось бы через прототип.

Я уже подсказывал ссылкой на статью в этой ветке один из способов наследования, и оно реализуется через прототип.

Sweet 05.09.2011 11:26

Хочешь через объект-прототип? Рекомендую самую обычную реализацию:
function B(){
  this.d = 2;
};
B.prototype.c = 1;

var b = new B;
alert( b.c + b.d );

yambbkru 08.09.2011 15:06

Спасибо, но мне не нужно реализовывать выдуманную мной задачу для примера другими способами! Мне нужен совет по поводу именно такой моей реализации. Пожалуйста, если кто может, помогите. Нужно те две функции как-то связать через прототип.


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