2013-10-08 3 views
0

Я пытаюсь создать несколько версий объекта, который имеет функцию init. Я попытался использовать функцию javascript «new», но в этом случае это не работает, и консоль уведомляет меня об этом, потому что это не функция. См. Код для более четкого описания того, что я пытаюсь сделать. Я понимаю, почему этот код будет предупреждать пункт два, а не пункт один, но я не знаю, как получить правильное поведение.создание нескольких экземпляров свойства объекта

var myApp = { 
menu: { 
     init: function (name) { 
      this.name = name; 
     }, 
     alertName: function() { 
      alert(this.name); 
     } 
    } 
} 

$(document).ready(function() { 
    var first = myApp.menu; 
    var second = myApp.menu; 
    first.init('item one'); 
    second.init('item two'); 
    first.alertName(); 
}); 

ответ

2

Вы должны клонировать объект. В javascript ваши переменные first и second являются двумя ссылками на один и тот же объект: при изменении first вы также изменяете second.

Вы можете использовать jQuery.extend() для клонирования вашего объекта.

var first = jQuery.extend(true, {}, myApp.menu); 
var second = jQuery.extend(true, {}, myApp.menu); 
+0

В чем основная причина использования jquery здесь, а не опция Object.create в ответе Tibos –

+0

@Peter Saxton. По двум причинам: во-первых, он уже использовал jQuery, поэтому для него не проблема использовать функцию jQuery. Во-вторых, функция «Object.create» недоступна до IE 9 ([Страница MDN Object.create] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create # Cross-browser_compatibility)). Когда есть выбор, я выбираю решение, обеспечивающее максимальную совместимость. – Elorfin

+0

Следует упомянуть некоторые соображения: 1) это решение имеет удар производительности при работе со многими объектами, поскольку оно клонирует объекты, а не использует прототипное наследование JS. 2) на странице MDN под таблицей совместимости имеется полиполк для этого точного варианта использования, который может использоваться, если OP хочет поддерживать старые браузеры. – Tibos

4

Вы можете использовать функции конструктора JavaScript, и называют new создать экземпляр различных объектов:

var myApp = { 
    menu: function(name){ 
     // if menu is called as a constructor function, `this` will refer 
     // to the object being built 
     this.name = name; 
    } 
} 

myApp.menu.prototype.alertName = function(){ 
    alert(this.name); 
} 

$(document).ready(function() { 
    var first = new myApp.menu('item one'); 
    var second = new myApp.menu('item two'); 
    first.alertName(); 
}); 

fiddle

+0

Я ищу для создания копий объекта, не использующего функцию-конструктор. Прежде всего, я могу использовать довольно большой патч кода, который я уже создал. –

+0

Ответы Корума и Тибоса действительны. – LeGEC

3

Причина оповещается только 'item two' потому, что когда вы делаете first = myApp.menu и second=myApp.menu, как first и second относятся к одному объекту. Когда вы устанавливаете свойство name этого объекта (this.name = name в init), обе ссылки указывают на тот же объект с измененным свойством.

Самый простой способ сделать это так:

var myApp = { 
    menu : { 
    init: function (name) { 
     this.name = name; 
    }, 
    alertName: function() { 
     alert(this.name); 
    } 
    } 
} 

var first = Object.create(myApp.menu); 
var second = Object.create(myApp.menu); 
first.init('item one'); 
second.init('item two'); 
first.alertName(); 

Демо: http://jsbin.com/OrEkaPe/1/edit

Object.create создает новый объект (дух) и устанавливает параметр как прототип для нового объекта. Когда вы получаете доступ к свойству нового объекта и его не существует, он будет доступен из прототипа вместо этого, предоставляя вам наследование, которое вы хотите.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

0

Декларирования объектов с {} фактически рядные инициализации, уже экземпляр, а не конструктор, одно решением для вашей проблемы можно было бы создать декларативный объект.

Пожалуйста, обратитесь к этой ссылке для получения дополнительной информации:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

Быстрая реализация вашей проблемы здесь:

http://jsbin.com/OsoWECA/1/edit

var myApp = { 
menu: function() { 
     this.init = function (name) { 
      this.name = name; 
     }; 
     this.alertName = function() { 
      alert(this.name); 
     }; 
     return this; 
    } 
}; 

$(document).ready(function() { 
    var first = new myApp.menu(); 
    var second = new myApp.menu(); 
    first.init('item one'); 
    second.init('item two'); 
    first.alertName(); 
    second.alertName(); 
}); 
0

Вы можете реализовать свой собственный new если вы хотите, это должно работать:

var myApp = { 
menu: { 
     init: function (name) { 
      this.name = name; 
     }, 
     alertName: function() { 
      alert(this.name); 
     }, 
     new: function() { 
      var func = function() {} 
      func.prototype = this 
      return new func; 
     } 
    } 
} 

$(document).ready(function() { 
    var first = myApp.menu.new(); 
    var second = myApp.menu.new(); 
    first.init('item one'); 
    second.init('item two'); 
    first.alertName(); 
}); 
Смежные вопросы