Я пытаюсь узнать больше о Javascript и немного покопаться в цепочке прототипов. Я хотел создать небольшое расширение для HTMLElement, когда столкнулся с этой проблемой.
Насколько я понимаю Object.create
, объект, который передается ему, используется для создания контекста для нового объекта и что первая ссылка в цепочке прототипов вновь созданного объекта будет указывать на объект, переданный методу Object.create
. В этом случае метод расширения, используемый в методе bar
ниже, показался мне правильным подходом, поскольку этот вновь созданный объект получит свой HTMLElement в качестве своего контекста.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<span id="test"></span>
<script>
HTMLElement.prototype.foo = function() {
let foo = Object.create(null);
foo.parentElement = this;
foo.parentElement.appendChild(document.createElement('div'));
}
HTMLElement.prototype.bar = function() {
let fooRenderer = Object.create(this);
fooRenderer.appendChild(document.createElement('div'));
}
document.getElementById('test').foo();
document.getElementById('test').bar();
</script>
</body>
</html>
Однако происходит то, что метод foo
работает правильно, добавляя новый дочерний элемент div
к <span id="test"></span>
, а bar
— нет.
Когда я открываю инструменты разработчика в своем браузере и пытаюсь следовать цепочкам прототипов двух объектов, для которых вызывается appendChild
, они выглядят почти одинаково:
foo Object
.parentElement <span#test2>
.__proto__ HTMLSpanElementPrototype
.__proto__ HTMLElementPrototype
.__proto__ ElementPrototype
.__proto__ NodePrototype
.appendChild
.__proto__ EventTargetPrototype
.__proto__ Object
.__proto__
get
set
fooRenderer Object
.__proto__ <span#test2>
.__proto__ HTMLSpanElementPrototype
.__proto__ HTMLElementPrototype
.__proto__ ElementPrototype
.__proto__ NodePrototype
.appendChild
.__proto__ EventTargetPrototype
.__proto__ Object
.__proto__
get
set
В этом примере я создал jsFiddle.
Может кто-нибудь объяснить мне, почему bar
не работает? Действительно ли bar
более правильный подход? Если да, то как его настроить для правильной работы?
Заранее благодарю за любую помощь!!!
HTMLSpanElement
в вашей цепочке прототипов, ваш объектfooRenderer
— это просто объект, а не настоящий узел DOM. - person Bergi   schedule 31.10.2016appendChild
, но не может его выполнить, потому что в этот момент он выполняется на объекте, а не на узле DOM? - person peinearydevelopment   schedule 31.10.2016Object.create
связывает цепочку прототипов и дает доступ ко всем этим методам, на самом деле он вообще не сохраняет ссылку на тот объект, который был передан? Есть ли способ поддерживать ссылку на этот объект таким образом, чтобы вызовappendChild
работал, или подход, показанный вfoo
выше, действительно является правильным подходом к этой проблеме? - person peinearydevelopment   schedule 31.10.2016let fooRenderer = this
(или, как в методеfoo
,let parentElement = this
). - person Bergi   schedule 31.10.2016