Моим основным источником информации по этому вопросу является урок Джеймса Шора по этому адресу: http://www.objectplayground.com/ ... После нескольких просмотров видео я забрал достаточно, чтобы связать воедино серию классов, ноЯ до сих пор не понимаю, что происходит под капотом. То, как Джеймс объяснил это классическим наследованием модели (которое, я полагаю, относится к использованию классов для организации данных, а не к более старому способу работы), работает следующим образом:
Когда оценивается любое выражение определения функции, дваобъекты созданы. Первый созданный объект - это конструктор (который я называю cStruct
для целей этого вопроса), и его можно идентифицировать по его члену, называемому prototype, который, по его словам и многим другим источникам, указывает на Prototype объекта функции или Function.prototype
. Но тогда это становится странным, потому что второй созданный объект - это прототип (или proType
), который, в свою очередь, идентифицируется его собственным членом, называемым конструктором, который указывает на cStruct
, а также имеет свой собственный член-прототип, который указывает на Объект Прототип объекта , или просто Object.prototype
. Ладно, достаточно просто (ха!), Но потом он (и другие источники) продолжит;Когда один класс расширяет другой, мы отказываемся от расширяющихся (более новых / более узких) классов proType
, заменяя их на новые, которые фактически указывают на расширенные (оригинальные / более старые / более широкие) классы proType
.
ХорошоТаким образом, в этом описании я попытался воссоздать модель наследования, используя только объекты с прототипами null
в качестве строительных блоков, чтобы я мог просматривать результаты в консоли, не просматривая все то, что я пока не понимаю. По сути, я ищу дымящийся пистолет наследства;доказательство того, что это не просто фокус . Кажется, что это возможно, но как только логика установлена в форме кода, неудивительно, что она не доставляет унаследованные свойства. Вы поймете, что я имею в виду.
Общая практика --- Три класса
function ExampleClass_A ( ) { }
function ExampleClass_B ( ) { }
function ExampleClass_C ( ) { }
Буквальная интерпретация
NOTE Это буквально эмулируемые классы. Они демонстрируют то, что, как я понимаю, происходит за кулисами во время написания классов. На этом примечании переменную c
можно почти игнорировать, пока мы не начнем расширять классы позже
a = Object.create( null );
b = Object.create( null );
c = Object.create( null ); // this represents the Object Prototype
cStruct_A = a;
proType_A = b;
proType_A.prototype = c;
cStruct_A.prototype = b;
proType_A.constructor = a;
delete a; delete b;
a = Object.create( null );
b = Object.create( null );
cStruct_B = a;
proType_B = b;
proType_B.prototype = c;
cStruct_B.prototype = b;
proType_B.constructor = a;
delete a; delete b;
a = Object.create( null );
b = Object.create( null );
cStruct_C = a;
proType_C = b;
proType_C.prototype = c;
cStruct_C.prototype = b;
proType_C.constructor = a;
delete a; delete b; delete c;
Обычная практика --- линейное расширение класса
РЕДАКТИРОВАТЬ @ Vog, я не уверен, что такое композиция объектов, но если бы мне пришлось угадывать, я бы сказал, что это был альтернативный шаблон расширения / создания экземпляров класса по сравнению с линейным, который яЯ написал в этом вопросе, где я должен был предположить, что какая-то форма наследования имела место в любом случае. Я, конечно, не готов принять один шаблон за другим, поскольку я просто пытаюсь понять, как вообще работает механизм, который делает эти шаблоны жизнеспособными, в первую очередь.
ExampleClass_B.prototype = Object.create( ExampleClass_A.prototype );
ExampleClass_C.prototype = Object.create( ExampleClass_B.prototype );
Буквальная интерпретация
ПРИМЕЧАНИЕ Если я правильно понимаю, для наследования должно работать proType
всех подклассов, следующих за мастер-классом, или один другой должен указыватьдо proType
своего родительского класса. Итак, здесь мы покончили с двумя из трех классов proType
и заменили их на те, которые были указаны в соответствующем «последующем» месте.
a = Object.create( null );
a.prototype = proType_A;
a.constructor = cStruct_B;
alt_proType_B = a;
cStruct_B.prototype = alt_proType_B;
delete proType_B;
delete a;
a = Object.create( null );
a.prototype = alt_proType_B;
a.constructor = cStruct_C;
alt_proType_C = a;
cStruct_C.prototype = alt_proType_C;
delete proType_C;
delete a;
CommonПрактика --- реализация
var exampleInstance_W = new ExampleClass_A(); //
var exampleInstance_R = new ExampleClass_B(); // randomly chosen names
var exampleInstance_T = new ExampleClass_C(); //
Буквальная интерпретация
a = Object.create( null );
a.prototype = proType_A;
nstance_W = a;
delete a;
a = Object.create( null );
a.prototype = alt_proType_B;
nstance_R = a;
delete a;
a = Object.create( null );
a.prototype = alt_proType_C;
nstance_T = a;
delete a;
Обычная практика --- задания
ExampleClass_A.prototype.prop_a = "test a,";
ExampleClass_B.prototype.prop_b = "test b,";
ExampleClass_C.prototype.prop_c = "test c";
Буквальная интерпретация
ПРИМЕЧАНИЕ Здесь я начинаю видеть, что что-то может быть не так
cStruct_A.prototype.prop_a = "test a,";
cStruct_B.prototype.prop_b = "test b,";
cStruct_C.prototype.prop_c = "test c";
// proType_A.prop_a = "test a"; //
// proType_B.prop_b = "test b"; // Kind of cool that this works
// proType_C.prop_c = "test c"; //
Тест --- общепринятая практика
console.log(
exampleInstance_T.prop_a, // successful log
exampleInstance_T.prop_b, // successful log
exampleInstance_T.prop_c, // successful log
);
Тест --- буквальная интерпретация
ПРИМЕЧАНИЕ Теперь для кульминации всех этих усилий. Как странно, что эти журналы дают разные результаты ...
console.log(
nstance_T.prototype.prop_a, // unsuccessful log
nstance_T.prototype.prop_b, // unsuccessful log
nstance_T.prototype.prop_c, // successful log
);
console.log(
nstance_R.prototype.prop_a, // unsuccessful log
nstance_R.prototype.prop_b, // successful log
nstance_R.prototype.prop_c, // unsuccessful log
);
console.log(
nstance_W.prototype.prop_a, // successful log
nstance_W.prototype.prop_b, // unsuccessful log
nstance_W.prototype.prop_c, // unsuccessful log
);
console.log( // Kind of lame that this does't work
nstance_W.prop_a, //
nstance_R.prop_b, // I mean it makes sense when you follow the
nstance_T.prop_c, // established logic, but at the same time
); // it means that I'm missing something.
Другими словами, если каждый Буквальная интерпретация кодовый блок просто эмулирует Обычную практику кодовый блок над нимпочему nstance_t
не имеет доступа к .prop_a
и .prop_b
? Это как-то связано с моей конфигурацией? Я упускаю суть? Помоги мне, ребята. Заранее спасибо.