Улучшить код
Привет. Код: http://jsfiddle.net/nz2c2cva/1/
надо переписать строку проверки условия, комментарий специалиста: "В конструкторе проверять this, если this не твой инстанс, то вызывать заново конструктор внутри себя уже с new", причём это решение должно быть лучше
if (this.$) {
return new $(selector);
}
Написал так: if (this instanceof window.constructor) , но специалист не принял, сказав, что ничего не улучшилось Так же, скажите, почему такой вариант лучше |
if (!(this instanceof $)) {
return new $(selector);
}
зачем учиться так, чтоб за тебя решали? |
не уверен, что правильно понял, но, похоже, ты хотел вот так сделать
<html>
<head>
<meta charset="windows-1251" />
</head>
<body>
<div class="class0"> <a href="">link</a> </div>
<div class="class0"></div>
<div class="class0"></div>
<script>
var $ = function (selector){
var o=Object.create($.prototype)
o.tags = document.querySelectorAll(selector);
return o
}
$.prototype.addClass = function(className){
for (var i = 0; i < this.tags.length; i++){
this.tags[i].classList.add(className);
}
return this;
}
$.prototype.copyHtml = function(){
var html=this.tags[0].innerHTML
for(var i = 1; i < this.tags.length; i++){
this.tags[i].innerHTML=html
}
}
$('div').addClass('class2').copyHtml();
</script>
</body>
</html>
|
И вот так,
var $ = function (selector){
this.tags = document.querySelectorAll(selector);
никогда не делай. Если уж используешь эту клоунаду, сначала рекурсивный вызов через new, а уже потом присваивание. Например,
$=function(selector){
if (!(this instanceof $)) return new $(selector);
this.tags = document.querySelectorAll(selector);
...
а в твоем случае, this===window, соответственно, ты туда срешь. |
А вообще, эту хрень проще безо всякого prototype написать, он тут ни к чему, по-моему
<html>
<head>
<meta charset="windows-1251" />
</head>
<body>
<div class="class0"> <a href="">link</a> </div>
<div class="class0"></div>
<div class="class0"></div>
<script>
var $ = function (selector){
var o=Object.create($)
o.tags = document.querySelectorAll(selector);
return o
}
$.addClass = function(className){
for (var i = 0; i < this.tags.length; i++){
this.tags[i].classList.add(className);
}
return this;
}
$.copyHtml = function(){
var html=this.tags[0].innerHTML
for(var i = 1; i < this.tags.length; i++){
this.tags[i].innerHTML=html
}
}
$('div').addClass('class2').copyHtml();
</script>
</body>
</html>
но все зависит от юзкейса, конечно. |
Цитата:
Спасибо, а почему так лучше? |
Цитата:
Код не надо изменять, это задание, которое почти выполнено |
Цитата:
|
Я понимаю, что такое конструктор и new.
Тем не менее, объясните, почему проверка if (!(this instanceof $))лучше, чем if (this.$) Кроме того, даже используя отладчик не пойму как работает этот код:
$.prototype.html = function(){
var clone = new $('_');
clone.tags = this.tags;
clone.toString = function() {
console.log("|");
return this.tags[0].innerHTML;
};
console.log("||");
return clone;
}
Точнее - в каком порядке исполняются инструкции return. Как я понял сначала отрабатывает return clone, затем функция toString()? Отладчик не заходит в toString |
Цитата:
Цитата:
а еще не понятно, зачем такое извращение
$.prototype.html = function(){
var clone = new $('_');
clone.tags = this.tags;
clone.toString = function() {
return this.tags[0].innerHTML;
};
return clone;
}
если достаточно
// getter
$.prototype.html = function(){
return this.tags[0].innerHTML;
}
http://api.jquery.com/html/ http://code.jquery.com/jquery-2.1.1.js |
Цитата:
$('div').html().addClass('class2').html() Я прошу ответить точно на мои вопросы либо дать напутствия, остальные вопросы решены |
Цитата:
Ему нужно было чтобы html() не прерывал цепочку вызовов (только не понимаю какой тогда смысл в его вызове ). Про toString ему подсказал его "специалист". Написал наскоряк. По идее надо создавать класс, наследующийся от $, с перекрытым toString. Причем в каждом вызове любого метода должен возвращаться новый инстанс, чтоб не тянулся один по цепочке. |
Цитата:
|
Цитата:
|
почему
if (!(this instanceof $)) лучше, чем if (this.$) ? Мне больше ничего не надо |
OlegALL, потому, что конструктор может быть вызван без new. А твоя проверка вообще не понятно что делает :)
|
Цитата:
Вторая проверяет что конструктор вызван в контексте объекта, у которого есть свойство $. Ну типа предполагается что был вызов Constructor(), и контекст тогда window, и проверяется window.$. Стоит сделать Constructor.call({$:1}) и твоя глюкавая проверка не сработает :D |
Спасибо. но я так и не понял, чем же второй вариант лучше. Какая разница, как проверять вызов конструктора?
Constructor.call({$:1})
- это вообще непонятно, к чемут.е. if (this.$)- это ненадёжно? когда-то сработает, а когда-то нет? |
Цитата:
|
Цитата:
$.call({$:1})
|
$.call({$:1})
- в смысле если $ примет значение 1, то не сработает? |
Запусти да посмотри.
|
но ведь
this.$вызывает $ без явного указания this, причём тут это
$.call({$:1})
? |
Немного ошибся. Тестируем твою проверку вот так:
function $(selector) {
if (this.$) {
alert('Вызван не как конструктор');
//return new $(selector);
} else {
alert('Вызван как конструктор');
}
}
$('x'); // ок
$.call({}, 'x'); // фэйл
(function(window, document) {
function $(selector) {
if (this.$) {
alert('Вызван не как конструктор');
return new $(selector);
} else {
alert('Вызван как конструктор');
}
}
$('x'); // фэйл
})(window, document);
Чет уж слишком легко ее наебать. |
ты хотел подчеркнуть, что this.$ зависит от внешнего окружения?
можешь объяснить, почему
(function(window, document) {
function $(selector) {
if (this.$){} // this.$ = undefined ???, хотя this = Window
}
}
function $(selector) {
if (this.$){} // this.$ = тело функции $; this = Window
}
и что это за функция-обёртка?
(function(window, document) {
})(window, document);
- извини, что надоел с вопросами, уже нет времени исследовать |
if(this === window) {
return new $(....);
}
|
if(this === window) и что? в обоих случаях this === windowэто true |
OlegALL, нет.
var $ = function(selector) {
alert(this === window);
if(this === window) return new $(selector);
}
$('bla');
|
уже совсем ничего не понимаю
скажите, вот это
(function(window, document) {
})(window, document);
- создаётся для задания области видимости (замыкания)? |
Ruslan_xDD, а если this - не window будет, то конструктор так и не будет вызван? Тоже проверка корявая. Че выдумывать то, а? Все уже придумано до нас.
|
danik.js, ну если он же и делает сам это всё для какого-то сайта, на кой ему нужно будет вызывать $ через call/apply?
В принципе, достаточно сделать:
if('$' in this) return new $(.....);
|
Это учебное задание, которое специально составлено на прокачку скиллов
|
Цитата:
|
danik.js, нет. Я не считаю, что '$' in this или this.$ - это через задницу. В jQuery вроде как раз так и написано.
Вот у тебя когда-нибудь была необходимость вызывать jQuery через call? Зачем её вообще через call кому-то понадобится вызывать? |
Цитата:
|
Цитата:
var
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
};
|
Цитата:
|
Цитата:
|
Правильно делаешь, ты ведь умнее разработчиков jQuery.
|
Цитата:
|
| Часовой пояс GMT +3, время: 03:47. |