2015-07-13 5 views
1

Я создал конструктор объекта в соответствии с макетом, предложенным Дугласом Крокфордом в его книге «Javascript: the good parts».jquery extend: что здесь происходит?

Этот конструктор возвращает объект that, добавив к нему различные элементы и методы. Одним из этих методов является функция клона, в которой JQuery extend используется для глубокого копирования объекта that.

Однако после создания клона случается что-то странное: изменение членов клона, похоже, не влияет на объект that из-за его методов.

Вы можете увидеть живой пример на JSFiddle

код:

var ctr = function() { 
    var that = {}; 

    that.a = 0; 

    that.f = function() { 
     return that.a; 
    }; 

    that.clone = function() { 
     return jQuery.extend(true, {}, that); 
    } 

    return that; 
} 

var obj1 = ctr(); 
var obj2 = obj1.clone(); 

obj2.a = 5; 

// Why are these values different???? 
console.log(obj2.a);  // prints '5', as expected 
console.log(obj2.f());  //prints '0'!!!! WHY?? 

Если мы используем this вместо that в JQuery расширить аргументы, он работает, как ожидалось.

Что здесь происходит?

+0

Потому что 'that' является постоянной ссылкой на исходный объект, а функция' f' никогда не упускает из виду этот объект. Таким образом, ваша функция 'f' в основном выполняет' obj1.a', когда она делает 'that.a'. Другими словами, обе 'obj1' и' obj2' используют одну и ту же функцию 'f', а функция' f' ссылается на 'obj1' * (' that') *. –

+0

так есть ли способ создать копию, методы которой ссылаются на новое «это»? – sangil

ответ

0

that.f закрывает thato1, и это закрытие копируется при использовании продления.

// from your updated JSFiddle 
var o1 = ctr(); 
var o2 = o1.clone(); 

o2.a = 5; 

// Why are these values different???? 
alert('Direct=' + o2.a + ', via Method=' + o2.f()); 
// prints 'Direct=5, via Method=0' 

o1.a = 3; 
alert('Direct=' + o2.a + ', via Method=' + o2.f()); 
// prints 'Direct=5, via Method=3'