Ben*_*rey 5 javascript jquery function object
我一直在寻找这个,但到目前为止还没有找到重复,我可能使用错误的关键字...
我试图暂时更改存储在对象中的函数,但是无法将其设置回原来的状态.
考虑一下:
// Set the options object
var options = {
success: function(){
console.log('Original Function Called');
}
}
// Save the options
$('#foo').data('bar',options);
Run Code Online (Sandbox Code Playgroud)
然后在另一个功能:
// Get the options
var options = $('#foo').data('bar');
// Store the old options
var old_options = options;
// Temporarily change the success function
options.success = function(){
console.log('Temporary Function Called');
}
// Save the options
// This allows the other functions to access the temporary function
$('#foo').data('bar',options);
// Do stuff here that uses the new options
// Reset the options to include the original success function
$('#foo').data('bar',old_options);
Run Code Online (Sandbox Code Playgroud)
我本来希望只显示Temporary Function Called一次,但它似乎完全用success临时回调替换旧的回调.
任何人都可以告诉我为什么以及如何解决这个问题?
UPDATE
我认为这样extend可以解决这个问题,但似乎问题可能会更深一些.我这次决定发布我的实际代码片段.阅读前请注意以下事项:
SM几乎只是别名jQuery,请忽略它.success并且error是提供给该功能的参数这是我的代码:
// Get the properties
var properties = $(form).data('autosave');
switch(parameter){
case 'save':
var old_properties = $.extend({},properties);
// Set the new callbacks if they have been supplied
properties.options.success = typeof success!=='undefined' ? success : old_properties.options.success;
properties.options.error = typeof error!=='undefined' ? error : old_properties.options.error;
// Save the properties
$(form).data('autosave',properties);
// Call the save method before setting the interval
SM(form)._as_save();
properties = $.extend({},old_properties);
// Save the old properties
$(form).data('autosave',properties);
// Clear the current interval
clearInterval(properties.interval);
// Call the save method periodically
properties.interval = setInterval(function(){
SM(form)._as_save();
},properties.options.interval);
break;
}
// Save the properties
$(form).data('autosave',properties);
Run Code Online (Sandbox Code Playgroud)
当您运行此代码时:
var old_options = options;
Run Code Online (Sandbox Code Playgroud)
您没有制作可以在以后恢复的整个对象的副本options.您只是保存对同一对象的引用.换句话说,是非常相同的对象,所以当你分配一个新值,你改变它在这两个和 -因为它们是同一个对象.old_optionsoptionsoptions.successoptions old_options
要解决此问题,您可以使用对象克隆功能制作对象的副本,然后可以稍后恢复该对象.由于您使用的是jQuery,因此可以将上面的行更改为:
var old_options = $.extend( true, {}, options );
Run Code Online (Sandbox Code Playgroud)
现在,当你改变时options.success,你只是在options对象中改变它.old_options不受影响,因此您以后的通话将成功恢复:
$('#foo').data('bar',old_options);
Run Code Online (Sandbox Code Playgroud)
有趣的是,即使options.success是异步回调(这可能来自名称),这仍然可以正常工作.这是因为无论以后代码调用该.success()方法,它们仍应保持对修改后的options对象的引用- 即使您在此期间已将旧对象恢复为元素的数据.至少有一个人希望这样; 如果其他代码挖回$().data()找到了.success回调,那么你就会有麻烦.
$.extend()上面的调用执行对象的"深度"(递归)副本options.也就是说,如果其中一个属性options本身就是一个对象,它也会克隆该对象,而不是仅复制对它的引用.
如果省略true参数,$.extend()则执行浅复制:
var old_options = $.extend( {}, options );
Run Code Online (Sandbox Code Playgroud)
这仍然会创建一个新对象并复制现有对象的所有属性,但如果其中一个属性本身就是一个对象,则它不会克隆该对象,它只是复制一个引用.如果它与您正在使用的对象的结构一起使用,则效率更高,否则您可以使用深层复制.
如果需要保存和恢复的属性/方法是主对象的直接子项,则浅层副本就足够了.这是一个你肯定需要深层复制的情况:
{
url: 'test',
events: {
success: function( data ) {
// ...
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里我们有一个带有events属性的对象,该属性本身就是一个对象,它有自己的一些属性/方法(在这个例子中是一个events.success()方法.如果你做这个对象的浅拷贝,原始和副本将共享一个共同的events对象.所以如果你做了这样的事情:
options.events.success = function(...) {...};
Run Code Online (Sandbox Code Playgroud)
你会实际上是更新,在这两个options和old_options.不好.这就是需要深层复制的地方.
| 归档时间: |
|
| 查看次数: |
6472 次 |
| 最近记录: |