Как базовая цепочка объектов/функций работает в javascript?
Я пытаюсь получить принципы работы функции jQuery в цепочке прямо в моей голове. Под этим я подразумеваю:
var e = f1('test').f2().f3();
У меня есть один пример для работы, а другой нет. Я отправлю их ниже. Я всегда хочу изучить первые принципиальные основы того, как что-то работает, чтобы я мог строить поверх него. До сих пор у меня было только поверхностное и свободное понимание того, как работает цепочка, и я сталкиваюсь с ошибками, которые я не могу устранить разумно.
Что я знаю:
- Функции должны возвращаться, ака "вернуть это";
- Цепные функции должны находиться в родительской функции, так как в jQuery,.css() является вспомогательным методом jQuery(), поэтому jQuery(). css();
- Родительская функция должна либо возвращать себя, либо сам новый экземпляр.
В этом примере работало:
var one = function(num){
this.oldnum = num;
this.add = function(){
this.oldnum++;
return this;
}
if(this instanceof one){
return this.one;
}else{
return new one(num);
}
}
var test = one(1).add().add();
Но этого нет:
var gmap = function(){
this.add = function(){
alert('add');
return this;
}
if(this instanceof gmap) {
return this.gmap;
} else{
return new gmap();
}
}
var test = gmap.add();
Ответы
Ответ 1
В JavaScript Функции являются объектами первого класса. Когда вы определяете функцию, это конструктор для этого объекта функции. Другими словами:
var gmap = function() {
this.add = function() {
alert('add');
return this;
}
this.del = function() {
alert('delete');
return this;
}
if (this instanceof gmap) {
return this.gmap;
} else {
return new gmap();
}
}
var test = new gmap();
test.add().del();
Назначив
new gmap();
для теста переменной, вы создали новый объект, который "наследует" все свойства и методы из конструктора (класса) gmap(). Если вы запустите фрагмент выше, вы увидите предупреждение для "добавить" и "удалить".
В приведенных выше примерах "this" относится к объекту window, если вы не обертываете функции в другой функции или объекте.
Мне сложно понять цепочку, по крайней мере, для меня, но как только я это понял, я понял, насколько мощным инструментом может быть.
Ответ 2
К сожалению, прямой ответ должен быть "нет". Даже если вы можете переопределить существующие методы (которые, вероятно, вы можете использовать во многих UA, но я подозреваю, что не могу в IE), вы все равно будете придерживаться неприятных переименований:
HTMLElement.prototype.setAttribute = function(attr) {
HTMLElement.prototype.setAttribute(attr) //uh-oh;
}
Лучшее, что вы могли бы избежать, это другое имя:
HTMLElement.prototype.setAttr = function(attr) {
HTMLElement.prototype.setAttribute(attr);
return this;
}
Ответ 3
Чтобы "переписать" функцию, но все же иметь возможность использовать исходную версию, вы должны сначала назначить исходную функцию другой переменной. Предположим пример объекта:
function MyObject() { };
MyObject.prototype.func1 = function(a, b) { };
Чтобы переписать func1
для цепочки, сделайте следующее:
MyObject.prototype.std_func1 = MyObject.prototype.func1;
MyObject.prototype.func1 = function(a, b) {
this.std_func1(a, b);
return this;
};
Здесь рабочий пример. Вам просто нужно использовать эту технику на всех стандартных объектах, которые, по вашему мнению, требуют цепочки.
К тому времени, когда вы выполните всю эту работу, вы поймете, что есть лучшие способы выполнить то, что вы пытаетесь сделать, например, используя библиотеку, в которой уже встроена цепочка. * cough * jQuery * cough *
Ответ 4
Во-первых, позвольте мне сказать, что я объясняю это своими словами.
Цепочка метода в значительной степени вызывает метод объекта, возвращаемого другой функцией/методом. например (с помощью jquery):
$('#demo');
эта функция jquery выбирает и возвращает объект jquery элемент DOM с демонстрацией id. если элемент был текстовым node (element), мы могли бы привязать метод возвращаемого объекта. например:
$('#demo').text('Some Text');
Итак, до тех пор, пока функция/метод возвращает объект, вы можете связать метод возвращаемого объекта с исходным выражением.
Что касается того, почему последние не работают, обратите внимание на то, где и когда используется ключевое слово this
. Скорее всего, это проблема контекста. Когда вы вызываете this
, убедитесь, что this
ссылается только на этот объект-объект, а не на объект окна/глобальную область.
Надеюсь, что это поможет.
Ответ 5
Просто вызовите метод как var test = gmap(). add();
поскольку gmap - это функция, а не переменная