Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Понимание ООП в JavaScript (https://javascript.ru/forum/misc/3070-ponimanie-oop-v-javascript.html)

kefi 15.03.2009 13:23

Понимание ООП в JavaScript
 
Чей-то почитал тут и там статьи и разное и запутался совсем . Что же такое ООП в JavaScript ...
Хотелось бы в этой теме провентилировать разные конкретные вопросы.

Первый вопрос , чтобы зацепиться, такой :

Если Array является объектом (встроенным) со свойствами constructor,length,prototype,concat,join etc..., то почему же я получаю эти свойства у его прототипа, а не у него самого :
alert(Array.prototype.hasOwnProperty("join") ) // true
 alert(Array.hasOwnProperty("join"))                // false
?

Тем более, что сказано в документации :
Этот метод не проверяет наличие свойства по цепочке прототипов; указанным свойством должен обладать именно сам объект. А пример выше показывает, что именно сам объект Array не обладает свойством, а обладает, наоборот, - прототип Array.prototype .
Короче , путаница получается - распутайте, плз.
Кстати, и в этом контексте также непонятно, почему :
var a = new Array(); alert(a.hasOwnProperty("join")) // false

PS Вот еще непонятные в связи с этим вопросом вещи :
var a = new Array(1,2);
alert(a.join(";")+"= a.join(';') Работает"); 

alert(a.hasOwnProperty("join")+"=a.hasOwnProperty('join') У собств НЕТ")    // false
alert(Array.hasOwnProperty("join")+"=Array.hasOwnProperty('join') У Array НЕТ") // false
alert(Array.prototype.hasOwnProperty("join")+"=Array.prototype.hasOwnProperty('join') У Array.prototype ЕСТЬ") // true
alert(Array.prototype.isPrototypeOf(a)+"=Array.prototype.isPrototypeOf(a)"); // true
alert(Array.isPrototypeOf(a)+"=Array.isPrototypeOf(a)"); // false
alert()
alert(Array.prototype.isPrototypeOf(Array)+"=Array.prototype.isPrototypeOf(Array)"); // false
alert(Array.isPrototypeOf(Array)+"=Array.isPrototypeOf(Array)"); // true
alert()
alert(Object.prototype.isPrototypeOf(Array)+"=Object.prototype.isPrototypeOf(Array)"); // true
alert(Object.isPrototypeOf(Array)+"=Object.isPrototypeOf(Array)"); // false
alert()
alert(Object.prototype.hasOwnProperty("constructor")+"=Object.prototype.hasOwnProperty('constructor')") // true
alert(Function.hasOwnProperty("constructor")+"=Function.hasOwnProperty('constructor')") // false


PPS. Может вообще кто-нибудь человеческим неформальным языком объяснить, что такое прототип, экземпляр объекта(или класса, не знаю , как правильно), объект(класс, не знаю , как в javascript надо говорить) ?

Gvozd 15.03.2009 13:38

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

kefi 15.03.2009 14:01

Цитата:

Сообщение от Gvozd (Сообщение 14354)
на всякий случай.читали вы это?особенно вторую статью.
там по моему вполне качественно объясняется.
если читали,и не поняли суть, то я даже не знаю как вам объяснить по другому

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

Gvozd 15.03.2009 14:17

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

kefi 15.03.2009 14:32

Цитата:

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

Тестировал в SciTE (точнее в WSH (WScript,Cscript) или в IE6SP1). Но это, точнее говоря не базовые , а встроенные в JavaScript типы (Array etc), поэтому если браузеры поддерживают javascript, то по встренным типам в javascript должна соблюдаться совместимость и никаких различий в их реализации быть не может .

Zeroglif 15.03.2009 14:34

Цитата:

Сообщение от kefi
Короче , путаница получается - распутайте, плз.

http://forum.dklab.ru/viewtopic.php?p=102575#102575
Цитата:

Сообщение от kefi
Если Array является объектом (встроенным) со свойствами constructor,length,prototype,concat,join etc

Вы смешиваете в кучу свойства разных объектов. У Array свои свойства, у Array.prototype свои. Array - это конструктор, функция, он не наследует от Array.prototype, от него наследуют новые массивы, "экземпляры" (new Array).

kefi 15.03.2009 14:35

Или вот такой совсем простой вопрос - что заносится, если заносится вообще, в свойство нового объекта prototype при его создании (т.е. (New {}).prototype чему равно и какого типа ) ?

Андрей Параничев 15.03.2009 14:43

kefi,
Прототип может быть только у конструктора (функции). Прототип это ссылка на объект, в котором будет производится поиск свойств, если они не были найдены в объекте, сформированным конструктором. С помощью прототипов в JavaScript реализуется наследование.

Возможно вам что-то разъяснит следующий код:
// Объявляем конструктор
var constr = function() {
    // Объявляем свойство объекта
    this.a = 1;
}

// Объявляем свойство прототипа
constr.prototype.b = 2;

// Создаем объект конструктора
var obj = new constr();

alert([obj.hasOwnProperty("a"), obj.a]); // true, 1
alert([obj.hasOwnProperty("b"), obj.b]); // false, 2


Свойства b в "собственных" свойствах объекта не было, но он был найден в прототипе. Вообще, рекомендую почитать статью о наследовании, я уверен, она ответит на ваши вопросы, касательно прототипов.

Zeroglif 15.03.2009 14:49

Погрузиться...
На глубину...

kefi 15.03.2009 14:51

2 Zeroglif > спасибо за ссылки, прочту, пока с пустой головой так быстро я не погружусь.
А пока :
Цитата:

Сообщение от Андрей Параничев
Прототип может быть только у конструктора (функции).

Где написано, или из чего следует, что он не наследуется от Object? Ведь вновь создаваемые объекты должны наследовать свойства от своих предков, общим для всех является объект Object ?

Андрей Параничев 15.03.2009 14:57

kefi,
Кто не наследуется? Конструктор? Или объект, созданный конструктором?

Только это тут не причем (и функция и объект, естественно, связаны цепочкой прототипов), мы говорим о том, что свойство prototype есть только у конструкторов (хотя в mozilla есть свойство __proto__ у объектов). Связь объект-прототип происходит в момент создания объекта. Т.е. когда вы вызываете new конструктор;.

Поскольку прототип это ссылка на объект, то вполне естественно, что все объекты, созданные конструктором, будут соединены с Object.prototype.

kefi 15.03.2009 15:30

Цитата:

Сообщение от Андрей Параничев
Кто не наследуется? Конструктор? Или объект, созданный конструктором?

Не то имел ввиду, имел ввиду Свойство prototype. Т.е. я хотел сказать что раз все объекты происходят от объекта Object, имеющее свойство prototype , то и они все должны иметь свойство prototype. Почему нет ?

Gvozd 15.03.2009 15:50

есть объекты.
а есть функции-конструкторы.
вот у функций-конструкторов(которые являются сами объектами, типа Function) есть свойство ptototype.оно есть только у функций, и влияет на создаваемые этими функциями-конструкторами объекты
у обычных же объектов нету свойтва prototype
есь внутренне своство(назовем его [[prototype]] к примеру), котороее ссылается на свойство prototype функции-конструктора, чоздавшей этот объект.если у объекта нету какого-то свойства, то оно ищется в объекте [[prototype]]. свойство [[prototype]] нигде не доступнов явном виде, и работать с ним напрямую невозможно(исключение:в мозилле оно доступно под именем __proto__), поэтому его имя для нас не так важно.

таким образом свойство prototype(не путать с [[prototype]])есть только у функций-конструкторов(любая функция может быть функцией-конструкотором, если внетри нее используются конструкция this)

Object - это функция конструктор тоже.она создает объект типа Object

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

свойство prototype функции-конструктора указывает какой объект должен быть в свойстве [[prototype]] создаваемого объекта.именно это [[prototype]] и называется прототипом объекта.

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

вот так вот сумбурно попытался объяснить суть дела
если не прав, кто-нибудь исправьте
PS еще раз:свойство prototype функции-конструктора не является прототипом функции.но оно указывает какой объект будет прототипом создаваемых объектов

Андрей Параничев 15.03.2009 15:56

Цитата:

Сообщение от Gvozd
свойство prototype функции-конструктора прототипом функции

Это не так:
var a = function() {}

a.prototype.hi = 1;

alert(a.__proto__ == a.prototype); // false


Цитата:

Сообщение от Gvozd
любая функция может быть функцией-конструкотором, если внетри нее используются конструкция this

Она может быть конструктором, даже если в ней не используется this.

Вообще, в спецификации есть довольно неплохие определения конструктора и прототипа:
Цитата:

Конструктор - объект типа Function, который создаёт и инициализирует объекты. Каждый конструктор обладает соответствующим объектом-прототипом, который используется для реализации наследования и разделяемых свойств.
Цитата:

Прототип - объект, используемый для реализации наследования структуры, состояния и поведения в ECMAScript. Когда конструктор создаёт объект, этот объект неявно ссылается на соответствующий этому конструктору прототип, чтобы использовать его для разрешения ссылок на свойства. Связанный с конструктором прототип доступен через выражение constructor.prototype, а свойства, добавляемые к прототипу объекта разделяются, посредством наследования, всеми объектами, разделяющими прототип.

Gvozd 15.03.2009 16:11

Андрей Параничев,
я опечатался. вернее не полностью напечатал фразу
уже исправил

Dmitry A. Soshnikov 15.03.2009 16:53

Цитата:

Сообщение от Gvozd
есь внутренне своство(назовем его [[prototype]] к примеру)

почему "к примеру"? оно именно так и называется в спецификации, так что можно смело так и называть его при описаниях ;)

kefi,

Ещё раз детальней постарайтесь прочитать материал по первой ссылке, которую Вам дал Zeroglif (там он достаточно хорошо и доступно объяснил). Если останутся вопросы (а они, конечно же, могут остаться, если Вы только начинаете изучать JS), то можно их уже будет локализовать и определить моменты, где именно остались неясности.

kefi 15.03.2009 16:57

Цитата:

Сообщение от Gvozd
свойство prototype функции-конструктора не является прототипом функции.но оно указывает какой объект будет прототипом создаваемых объектов

var constr = function(){ this.a = 1;}
//var constr = new Function("this.a = 1;") // <- или так 

//alert([constr.__proto__ == constr.prototype,constr.__proto__ == constr.constructor.prototype]); // false , true
alert([constr.prototype == constr.constructor.prototype, constr.prototype, constr.constructor.prototype]); 
// false,[object Object], function prototype() { [native code] }


Т.е. прототипом вновь создаваемых объектов подобных constr , будет constr.constructor.prototype==function prototype() { [native code] } ,
а прототипом функции function(){ this.a = 1;} будет constr.prototype== [object Object] .
?

Dmitry A. Soshnikov 15.03.2009 17:20

Цитата:

Сообщение от kefi
Т.е. прототипом вновь создаваемых объектов подобных constr , будет function prototype() { [native code] } ,
а прототипом функции function(){ this.a = 1;} будет [object Object] .

constr - у Вас конструктор. Естественно, он тоже объект, и у него есть свой прототип - __proto__:

alert(constr.__proto__); // оригинальный Function.prototype, который равен  function () {}

alert(constr.constructor.prototype); // то же самое, т.к. конструктор у constr - Function

alert(constr.constructor.prototype === constr.__proto__);


Однако, т.к. constr сам конструктор, то все порождённые от него объекты также будут иметь свой __proto__:
var a = new constr();

alert(a.__proto__); // объект, на который так же указывает constr.prototype (пока эта ссылка есть)

alert(a.__proto__ === constr.prototype); // действительно, они указывают на один объект


Поэтому родной прототип конструктора constr - это constr.__proto__, а прототип порождаемых от constr объектов - constr.prototype (порождённые объекты от constr будут смотреть на constr.prototype через .__proto__. Причём, ссылка constr.prototype может исчезнуть позже, а порождённыйОбъект.__proto__ - нет).

Gvozd 15.03.2009 17:31

прототипом вновь создаваемых объектов типа constr,т.е. создаваемых при помощи
obj=new constr()

будет
obj.__proto__==constr.prototype==obj.constructor.prototype

то есть объект [object Object]

прототипом же функции constr , создаваемой
var constr = function(){ this.a = 1;}//так
var constr = new Function("this.a = 1;") // <- или так

будет
constr.__proto__==Function.prototype==constr.constructor.prototype

то есть function(){}

PS малясь не успел,но дуаю будет полезно

kefi 15.03.2009 18:09

2 Gvozd> Ну да, я Вас понял буквально и неверно , - что прототип объекта - это объект.prototype,
Т.е. ВСЕГДА нужно понимать так, что прототип объекта - это прототип его конструктора, т.е. объект.constructor.prototype,

Gvozd 15.03.2009 18:57

блин, да нет же.
интересно где я не так начал объяснять.

__proto__(или же [[prototype]], что есть одно и тоже) и prototype - это разные вещи.


__proto__(или же [[prototype]]) это и есть прототип объекта.
если у объекта не находится какое-то свойство, то оно начинает искатся в его прототипе.затем в прототипе прототипа.и так пока не дойдет до самого верхнего прототипа - объекта [object Object]

prototype - это такое свойство у функции-конструктора, которое определяет какой прототип будет у объектов создаваемых этим конструктором.НО, это НЕ ПРОТОТИП самой функции.
Прототипом самой функции является пустая функция function(){}

ТО ЕСТЬ ЭТО НЕВЕРНО:
Цитата:

Сообщение от kefi
прототип объекта - это объект.prototype

на самом деле правильно
Цитата:

прототип объекта - это объект.[[prototype]](или же объект.__proto__). и это является функция_конструктор.prototype
ТАКЖЕ НЕВЕРНО:
Цитата:

Сообщение от kefi
прототип объекта - это прототип его конструктора, т.е. объект.constructor.prototype

на самом деле правильно:
Цитата:

прототип объекта - это свойство prototype(А НЕ ПРОТОТИП) его конструктора, т.е. объект.constructor.prototype
на примере:
//constr- функция-конструктор.все что будет объявлено посредством (new constr()) будет иметь тип constr
var constr = function()
	{this.a = 1;}
//var constr = new Function("this.a = 1;") // <- или так 
//Function - функция-конструктор для всех прочих функций

alert(constr.__proto__==Function.prototype);//TRUE
//прототипом функции constr(а она помимо всего прочего также является объектом) является объект, заданный в свойстве prototype ее конструктора
alert(constr.__proto__);//function(){}
//прототипом функции constr является просто пустая функция.
//у всех функций один общий прототип.этот прототип является объектом-пустой функцией

//------------------------------------------------------------------------------------------------
//вот мы задаем, что у всех объектов, созданных при помощи new constr() будет общий прототип.
//прототип функции от это не меняется
constr.prototype={'b':2}

//а вот мы создаем объект при помощи нашего конструктора
obj=new constr()

alert(obj.__proto__==constr.prototype);//TRUE
//прототипом объекта, созданного при помощи конструктора constr является объект, заданный в свойстве prototype его конструктора

alert(obj.__proto__);// этот объект: {'b':2}

alert('obj.a='+obj.a)//1 .свойство берется из самого объекта
alert('obj.b='+obj.b)//2 .свойство берется из прототипа объекта

obj2=new constr()//создадим еще один объект
//для него пока что свойства идентичны
alert('obj2.a='+obj2.a)//1 .свойство берется из самого объекта
alert('obj2.b='+obj2.b)//2 .свойство берется из прототипа объекта
//переопределим его свойства:

obj2.a=11
obj2.b=12
//посмотри как это повлияло на первый и второй объекты:
alert('obj.a='+obj.a)//1 .свойство берется из самого объекта.никакого влияниея второго объекта
alert('obj.b='+obj.b)//2 .свойство берется из прототипа объекта.никакого влияниея второго объекта
alert('obj2.a='+obj2.a)//11 .свойство берется из самого объекта
alert('obj2.b='+obj2.b)//12 .свойство берется из самого объекта.прототип остался неизменным
//как видим изменение своства b второго объекта никак не повлияло на прототип, и на первый объект.
//ну, совсем никак


//теперь изменим свойство b у ихнего прототипа:
constr.prototype.b=22
alert('!obj.b='+obj.b)//22
alert('!obj2.b='+obj2.b)//12
//как видим изменение прототипа затронуло только первый объект
//потому что у первого свойство b не было переопределено .а у второго было.
//поэтому первый все еще берет свойство из протипа, а вот второй берет уже собственное свойство b, которое мы назначили выше

//попробуем поменять свойство prototype у функции-конструктора
constr.prototype={'b':32}
alert('obj.b='+obj.b)//22
alert('obj2.b='+obj2.b)//12
//как видим смена свойства prototype у функции-конструктора никак не сказалась на УЖЕ созданных объектах.
//зато все последующие созданные объекты будут иметь НОВЫЙ прототип, никак не связанный с прототипом старх объектов

obj3=new constr()
alert('obj3.b='+obj3.b)//33.это свойство его прототипа.но не прототипа предыдущих объектов
alert([ obj.__proto__== obj2.__proto__,
				obj3.__proto__== obj.__proto__,
				obj3.__proto__== obj2.__proto__ ])//TRUE,FALSE,FALSE
//как видим у первых двух объектов прототип совпадает между собой.
//а  вот у третьего не совпадает ни с прототипом первого, ни с прототипом второго


PS запускать для наглядности в Mozilla
также будет легче, если вы поставите себе firebug, и замените все alert на console.log

Gvozd 15.03.2009 19:00

надеюсь этот пример разъяснит вам на пальцах, как это все работает.
я старался

Dmitry A. Soshnikov 15.03.2009 19:27

Цитата:

Сообщение от Gvozd
alert('obj2.b='+obj2.b)//12 .свойство берется из прототипа объекта

Опечатался. Свойство берется уже из объекта.

Молодец, хорошо описал. ;)

Gvozd 15.03.2009 19:34

Dmitry A. Soshnikov,
спасибо.исправил

kefi 15.03.2009 20:56

2 Gvozd > Исправьте и у меня , если что далее неверно :

Прототип(тип или класс родителя) объекта - это свойство prototype конструктора объекта ( объект.constructor.prototype ).

На примере встроенного объекта Array можно сделать следующие высказывания:

1) Array.prototype // - ссылка на прототип(или что то же самое тип родителя) объектов, создаваемых с помощью конструктора Array, который сам является объектом типа Function ; Т.е. :
Function===Array.constructor // - конструктор Array - есть Function (или , что то же самое, - его тип есть Function)
Function.prototype===Array.constructor.prototype // - тип родителя объекта Array (являющегося конструктором) тоже определяется через свойство prototype его конструктора ( которое == function prototype() {[native code] } )

2) Array.prototype.constructor===a.constructor // - ссылка на конструктор объектов а, которые имеют тип Array (,где var a=new Array() )

3) Array.prototype===a.constructor.prototype // - прототип (тип родителя) объекта а [strike](== function Array() { [native code] } )[/strike]

4) Array===a.constructor // - [strike]тип (класс) объекта а [/strike]- объект-конструктор объекта а ( == function Array() { [native code] } )

Gvozd 15.03.2009 22:04

Цитата:

Сообщение от kefi
Прототип(тип или класс родителя) объекта - это свойство prototype конструктора объекта ( объект.constructor.prototype )

во первых в JS Нету понятия класс(хотя это можно симитировать)
во вторых тип объекта и прототип - разные вещи.
тип объекта определяется каким конструктором он был создан.
а прототип свойством prototype конструктора, на момент создания объекта
ну, и в третьих родителем объекта является его прототип, а не его конструктор
прототип объекта-это не тип и не класс объекта, а объект, постоянно висящий в памяти, и который можно считать родителем этого объекта
----------------------------------------------------------------------
Цитата:

Сообщение от kefi
1) Array.prototype // - ссылка на прототип(или что то же самое тип родителя) объектов, создаваемых с помощью конструктора Array,
прототип которого Function;

не совсем так:
у Array прототип не Function, а объект созданный с помощью Function
Array.__proto__!=Function
Array.__proto__==(function(){})//тут на самом деле будет FALSE.но суть примерно такая, что прототип конструктора Array - пустая функция

Таким образом Function - конструктор конмтруктора Array, а пустая функция(не любая, а вполне такая определенная, висящая в памяти со старта скрипта, и созданная интепретатором) яляется прототипом конструктора Array
----------------------------------------------------------------------
Цитата:

Сообщение от kefi
2) Array.prototype.constructor===a.constructor // - ссылка на конструктор объектов а, которые имеют тип Array (,где var a=new Array() )

это равенство более полно выглядело бы так:
Array.prototype.constructor===a.constructor===Arra y
то есть конструктор у объекта a и у его прототипа одинаков, и это есть функция Array
----------------------------------------------------------------------
Цитата:

Сообщение от kefi
3) Array.prototype===a.constructor.prototype // - прототип (тип родителя) объекта а (== function Array() { [native code] } )

Array.prototype - прототип объекта a(но тип родителя)
Array - тип родителя объекта a( и при этом тип самого объекта a)
Цитата:

Сообщение от kefi
Array.prototype===a.constructor.prototype (== function Array() { [native code] } )

Это вообще не верно
Array.prototype===a.constructor.prototype == new Array()//опять-таки тут будет на самом деле FALSE. по сути дела заместо (new Array()) должен быть так же висящий в памяти объект типа Array
----------------------------------------------------------------------

половина исправлений была скорее на терминологию

Zeroglif 15.03.2009 22:45

Количество слов "prototype" в ветке взрывает мозг. :dance:

сорри за оффтоп

Gvozd 15.03.2009 23:02

Zeroglif,
ты мне тут это.того.
не загаживай такую прелестную ветку оффтопом:rolleyes:
PS на самом деле мне эта тема очень нравится.
гораздо приятней помочь человеку разобратся в такой довольно нелегкой вещи как прототипирование(я сам статью Кантора перечитывал раза три, прежде чем до меня тогда начало доходить.и вообще, я сперва думал, что prototype==[[prototype]]), чем заставлять людей хоть немного потрудится самим, после того как объясниш ему алгорит простейшей задачи.
во всяком случае тут видна усердная работа человека и стремление разобратся, а не получить решение конкретной задачи "на блюдечке"

Zeroglif 15.03.2009 23:09

Цитата:

Сообщение от Gvozd
я долгое время думал, что prototype==[[prototype]]

Чаще всего так и есть. ;)

Gvozd 15.03.2009 23:13

Zeroglif,
вообще-то я думал, что
obj.prototype==obj.[[prototype]]

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

Zeroglif 15.03.2009 23:22

Цитата:

Сообщение от Gvozd
мне эта тема не сразу

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

Gvozd 15.03.2009 23:26

Zeroglif,
хватит ломать мне мозг.
он и так разрушен радио "Воруй, Убивай" и проектом "Нежное Это"
а тут еще прототипы, до кучи

kefi 16.03.2009 20:07

Цитата:

Сообщение от Gvozd
половина исправлений была скорее на терминологию

Так в этом-то видно и дело. Но пока попытаюсь еще задать вопросы, пользуясь своей терминологией. Непонятки там, где стоят ?? :
//var constr = function() {} ; /* или так */ var constr = new Function() /* или так */ function constr() {} 
var constr = new Function() // constr - есть объект(экземпляр) типа(класса) Function ( Function - это не родитель объекта constr , а его тип(класс) ) 
//  - кроме создания объекта-конструктора constr еще выполяется следующее :
//   - создаётся новый объект-прототип (ссылка на который заносится в constr.prototype) ; 
//   - значением свойства constructor этого объекта становится создавший его объект-конструктор (constr.prototype.constructor=constr); 
//   - значением свойства prototype объекта-конструктора становится вновь созданный объект  - А что это за объект ??- непонятно.

var a=new constr()          // a      - есть объект(экземпляр) типа(класса) constr   ( constr   - это не родитель объекта a , а его тип(класс) )
document.write([
// Иерархия объектов пользователя (прикладных объектов)--------- :

a.constructor.prototype===a.__proto__,
a.constructor.prototype===constr.prototype,
a.__proto__===constr.prototype, // родитель объекта a (ссылка на родителя содержится в свойстве prototype конструктора объекта a)

//constr.prototype.constructor, // ==function anonymous() { }  <- конструктор родителя
constr.prototype.constructor.prototype=='[object Object]' , constr.prototype.__proto__ =='[object Object]',
constr.prototype.constructor.prototype===constr.prototype.__proto__ , // FALSE ??

constr.prototype.constructor===constr, // TRUE (значением свойства constructor родителя будет создавший его объект-конструктор constr );

// К слову, также не понятно, почему :
a.__proto__.constructor===a, //FALSE , т.к. а - не есть объект-конструктор ??
constr.prototype.__proto__.__proto__===null,     // TRUE  - вершина
constr.prototype.__proto__===Object.prototype,   // TRUE 

])

Т.е. я пытался, но мне не удалось построить стройную и понятную, где был бы понятен каждый объект в цепи наследования, иерахию объектов от a к родоначальнику Object.prototype, у которого уже нет родителя.

Gvozd 16.03.2009 20:48

Цитата:

Сообщение от kefi
// - значением свойства prototype объекта-конструктора становится вновь созданный объект - А что это за объект ??- непонятно.

до тех пор, пока вы не переопределите свойство prototype объекта-конструктора, это просто пустой объект типа constr (то есть его конуструктором считается функция constr), с пустым набором свойств
__________________________________________________ ______
Цитата:

Сообщение от kefi
constr.prototype.constructor.prototype=='[object Object]' , constr.prototype.__proto__ =='[object Object]',
constr.prototype.constructor.prototype===constr.pr ototype.__proto__ , // FALSE ??

несмотря на то что левая и правая часть последнего сравнения являются объектами, сравнение ложно.
потому что это разные объекты
//конструктор свойства prototype конструктора является сам конструктор
constr.prototype.constructor==constr//из этого следует =>
constr.prototype.constructor.prototype==constr.prototype
//такую конструкцию можно дополнять циклично на любой уровень вложенности
//--------------------------------------------------------------
прототипом свойства prototype конструктора является свойство prototype конструктора Object.
constr.prototype.__proto__==Object.prototype
//--------------------------------------------------------------
constr.prototype!=Object.prototype
//зато:
constr.prototype.__proto__==Object.prototype
//то есть прототипом свойства prototype является свойство prototype Object()

__________________________________________________ ______
Цитата:

Сообщение от kefi
// К слову, также не понятно, почему :
a.__proto__.constructor===a, //FALSE , т.к. а - не есть объект-конструктор ??

а мне непонятно с чего вы решили что это должно быть так
a //объект
a.__proto__ //прототип объекта(является экземпляром типа constr)
a.__proto__.constructor //конструктор прототипа
a.__proto__.constructor==a.constructor//у прототипа и у объекта общий конструктор
a.__proto__.constructor==constr//и этот конструктор - функция constr, а не объект a

__________________________________________________ ______
на закуску:
var a=new constr()          // a      - есть объект(экземпляр) типа(класса) constr   ( constr   - это не родитель объекта a , а его тип(класс) )
alert(a.__proto__==constr.prototype)//TRUE
constr.prototype=new constr()
alert(a.__proto__==constr.prototype)//уже FALSE, так как прототип объекта остался тем же, а вот свойство prototype его конструктора уже изменилось

__________________________________________________ ______
По поводу же иерахии напишу так:
var constr = new Function()
var a=new constr()
console.log([
a.__proto__==constr.prototype, //прототип объекта
constr.prototype.__proto__==Object.prototype, //прототип прототипа объекта
Object.prototype.__proto__==null //прототип прототипа прототипа объекта уже не существует
])

Dmitry A. Soshnikov 16.03.2009 21:31

Цитата:

Сообщение от Gvozd
до тех пор, пока вы не переопределите свойство prototype объекта-конструктора, это просто пустой объект типа constr

это просто объект, как, если бы: new Object(), просто свойство constructor этого нового объекта будет ссылаться на конструктор (constr).

Цитата:

Сообщение от Gvozd
a.__proto__.constructor==a.constructor//у прототипа и у объекта общий конструктор

Точнее, не общий конструктор, а один и тот же конструктор, поскольку объект "а" не имеет родного свойства constructor, и оно будет найдено в прототипе (т.е. уже здесь начинается наследование)

Zeroglif 16.03.2009 21:39

Gvozd,
Цитата:

//у прототипа и у объекта общий конструктор
Разные. Общим можно назвать свойство 'constructor' (в плане получения значения).

kefi 16.03.2009 21:45

Цитата:

Сообщение от Gvozd
// К слову, также не понятно, почему :
a.__proto__.constructor===a, //FALSE , т.к. а - не есть объект-конструктор ??
а мне непонятно с чего вы решили что это должно быть так

Оттого, что у объекта-конструктора это вот так :
constr.prototype.constructor===constr
а у объекта-НЕконструктора это НЕтак . короче , заплутал малость, решил , что constr.prototype=constr.__proto__

Т.е. непонятка мешает : отчего же свойство constructor недоступно для объекта, не являющегося конструктором ?

PS. Остальное позже разберу.

Dmitry A. Soshnikov 16.03.2009 21:46

Цитата:

Сообщение от Zeroglif
Разные.

Да, чтобы совсем очень терминологически точно, и я должен был написать:

"не общий конструктор, а один и тот же объект, к которому приведёт свойство constructor" (хотя, конечно, это и имелось в виду)

Zeroglif 16.03.2009 21:59

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

Gvozd 16.03.2009 22:11

Цитата:

Сообщение от kefi
Т.е. непонятка мешает : отчего же свойство constructor недоступно для объекта, не являющегося конструктором ?

вы имеете в виду a.constructor?
вообще-то он доступен:
alert(a.constructor)//зависит от способа создания конструктора
//если var constr = new Function(), то будет анонимная функция
//если function constr(){} , то будет именованая функция constr()
console.log(a.constructor==constr)//TRUE


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