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

bot87 02.04.2012 00:02

свойство в prototype
 
function Animal(name) {
  this.name = name;
}
 
Animal.prototype.eats = true;
 
Animal.prototype.run = function() {
  this.eats = false;
  alert(this.name + ' бежит!');
};
 
var animal = new Animal('Зверь'); // (1)
animal.run();

меня интересует prototype.eats.Можно объяснить зачем добавлять свойство в прототип и что оно дает.Как оно наследуется?

dmitriymar 02.04.2012 00:04

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

bot87 02.04.2012 01:00

огромное спасибо

bot87 02.04.2012 01:20

как ее почитать??КХорошо излагаеш мысли.:)

bot87 02.04.2012 01:26

А вот эту штуку с this.блаБлаБла = 221
внутри конструктора добавили для пущего выебона, чтобы конструктор обьекты не только с прототипа копировал, а еще и что-то новое добавлял.


Типа общие свойства для клонов задаются в прототипе а функция конструктор делает их особенными?я думал наоборот:blink:

devote 02.04.2012 01:57

да но у прототипов есть огромный на мой взгляд минус, то что у родительский прототипов для всех дочерних конструкторов одни общие приватные переменные. И этот недостаток приводит к тому что на прототипной основе очень сложно делать сложное программное обеспечение. В чем все же ООП намного привлекательнее прототипных наследований.

вот небольшой пример иллюстрирующий то как приватные переменные пересекаются.
// создаем родительский объект с приватной переменной
var Parent = (function() {
    var a = "test"; // наша приватная переменная
    var Fn = function() {}
        // публичные методы
    Fn.prototype.changeTest = function() {
            a = "new value";
    }
    Fn.prototype.show = function() {
            alert( a );
    }
    return Fn;
})();

// дочерний конструктор, который наследует Parent
function Child() {}

function F(){}
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;

var q = new Child(); // создаем один экземпляр Child
var w = new Child(); // создаем второй экземпляр Child

q.show(); // отобразим текущее приватное значение
q.changeTest(); // сменим приватную переменную

w.show(); // отобразим приватную переменную через другой экземпляр.
Результат того что для каждого экземпляра нужно пересоздавать приватные переменные. Конечно же это можно обойти в JavaScript но это уже далеко станет не прототипным наследованием.

devote 02.04.2012 02:13

я поправил пример.
Цитата:

Сообщение от Maxmaxmахimus
а приватные свойства нужно именовать как __prop

Будь добр пример мне покажи.

devote 02.04.2012 02:42

Цитата:

Сообщение от Maxmaxmахimus
devote, дело в том что this определяется по форме вызова в зависимости от того что слева от функции через точку.

я вкурсе откуда возникает this и кто/что в него кладут. Ты мне пример покажи реализации того что бы для каждого нового дочернего экземпляра создавались собственные приватные переменные, и не просто имитация приватных свойств, которые все равно можно достать из дочернего элемента, а именно что не на есть приватные. Которые как я сказал будут для каждого экземпляра собственные. Возьмем пример с PHP:
class Parent {
    private var $variable = "lalalala";
    public function setPrivate( $val ) {
        $this->variable = $val;
    }
    public function getPrivate() {
        return $this->variable;
    }
}

class Child1 extends Parent {
}

class Child2 extends Parent {
}

$child1 = new Child1();
$child2 = new Child2();

echo $child1->getPrivate(); // выведет "lalalala"
$child1->setPrivate( 'new value' );
echo $child1->getPrivate(); // выведет "new value"

echo $child2->getPrivate(); // выведет "lalalala"

devote 02.04.2012 02:43

Цитата:

Сообщение от Maxmaxmахimus
и тут работаешь с ними как обычно, зная что то что начинается с __ это приватные поля. так же желательно исключить их из перечисления и.т.п.

Я так и понял что ты мне паблик предложишь, что не является совсем тем что нужно.

devote 02.04.2012 02:48

Цитата:

Сообщение от Maxmaxmахimus
что это значит?

это значит что ты мне предлагаешь имитировать приватные переменные которые можно достать из любого места, то-есть в любом случае они не приватные а публичные.
Цитата:

Сообщение от Maxmaxmахimus
почему?

потому что это не чистый приват, а имитация.

devote 02.04.2012 02:54

Цитата:

Сообщение от Maxmaxmахimus
в чем отличия, прошу пример.

возьми свой пример и в конце кода напиши:
alert( q.__private ); // увидишь 'text'
а нужно видеть undefined

devote 02.04.2012 03:14

deleted

devote 02.04.2012 03:24

Цитата:

Сообщение от Maxmaxmахimus
devote, оч интересно, я посмотрю завтра, а зачем тебе видеть undefined запрашивая доступ к приватному свойству?
это единственный недостаток подхода с подчеркиваниями? отсутствие генерации undefined?

Это большой недостаток прототипного наследования, который не создает новый экземпляр а юзает старый, просто с иным контекстом... Конечно это облегчает язык в целом, как в обучении так и построении быстрых решений. Так же как отметили выше не жрет память, но с таким подходом сложно писать что-то реально крупное и полноценное. Я не говорю что JavaScript плох, мне он конечно не особо привычен, но жить можно. Я привык к ООП и там все предсказуемо, но тут увы не предскажешь чей ты контекст получишь.
Цитата:

Сообщение от Maxmaxmахimus
а зачем тебе видеть undefined запрашивая доступ к приватному свойству?

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

devote 02.04.2012 03:39

Цитата:

Сообщение от Maxmaxmахimus
ты вегда получаешь контекст того относительно чего вызываешь.

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

Сообщение от Maxmaxmахimus
но ведь общепринято что 2 черточки вначале это означает приватность, так же как и название конструкторов с большой буквы.

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

devote 02.04.2012 03:51

вот пример:
кто-то написал библу.. допустим ты написал библиотеку, очень удобную и т.д. вот типо часть ее кода:
function YouMethod() {
    this.__private = [];
    this.blah = function() {
        this.__private.join( "\n" );
    }
}
В итоге я беру твою либу, допустим минифицированую, понятно дело что в коде я без пива не пойму. Ну тоесть код то сжат. Ну подумаю все чики и начну дописывать свое к ней:
function YouMethod(){this.__private = [];this.blah=function(){this.__private.join( "\n" );}}

function MyMethod() {
    this.__private = {}; // я решил назвать так приватную, но не знал что у теб она тоже так называется. И имеет другой тип.
    this.tata = function(){}
}
MyMethod.prototype = new YouMethod();
var lala = new MyMethod();
lala.blah(); // вызовет ошибку
В итоге происходит конфликт, твоя функция думает что там в качестве приватной лежит массив, но так как я назвал свою переменную тоже так же как и ты, то теперь эта переменная имеет тип объекта и твоя функция вызовет ошибку обратившись к приватной переменной. Это и называется перекрытие, конфликт.

melky 02.04.2012 09:05

Цитата:

Сообщение от Maxmaxmахimus (Сообщение 166413)
я думаю энциклопедию в таком стиле написать))) типа вики. где есть краткая формулировка (при наведении на слово) и развернутая статья, при клике по слову(ну это как в вики). только в одно рыло не смогу

запили книжку на юкозе, попутно запилив красивый responsive дизайн с нуля.

devote 02.04.2012 14:36

Maxmaxmахimus,
что то ты многовато написал, какой то чуши... без обид, но не нужно мне объяснять что такое прототипы, что такое классы а что такое ООП. Поверь я знаю что это такое.. Вся речь лишь началась с того что прототипы в отличии от классов полный порожняк.

И не надо мне рассказывать где тут моя/твоя переменная... ты даже вникнуть не можешь в то, о чем я тебе говорю, и начинаешь потом писать непонятно что. Тебе нужно поучить программирование на классах, то-есть ООП и тогда ты поймешь о чем я говорю и что я имею вииду.

А зная лишь один JavaScript ты никогда не поймешь того в чем различается ООП от того что умеет JS.

devote 02.04.2012 15:47

Maxmaxmахimus,
ну вот видишь, ты снова меня не понял.. я не кричу о том что в JS это невозможно, речь идет о прототипах а не о языке в целом. Я в курсе что на JS можно хорошо писать при желании. Снова повторюсь, речь идет о прототипах. Тоесть сравнение классового наследования с прототипным наследованием. А не о языках и ООП в целом.

devote 02.04.2012 16:13

Maxmaxmахimus,
ладно я устал с тобой спорить и пытаться объяснить в чем различие настоящего полноценного ООП от Прототипного Программирования, который лишь пытается сделать вид что он полноценный ООП язык, потому как имеет возможность работать с сущностями объектов и имеет наследование. Но это не говорит о его полноценности, умение наследовать не дает языку понятия ООП. Умение работать с объектами как с сущностями не дает языку понятие ООП. Я не говорю что ООП это классы, ООП это умение делать все то и в полной мере что я описал выше, а основное отличие и важность уметь инкапсулировать. И помимо этого другие вещи. Прототипное программирование это лишь некий подтип объектного программирования. Но не полноценный, о чем я и пытаюсь втолковать.

Все на этом разговор считаю дальше нет смысла продолжать.


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