Jquery 插件中$.extend调用的差异?
我相信这个问题与此有关:谁能回答这个问题,谁就可能回答这个问题 我注意到关于jQuery的一些东西,如果我将我的插件称为:Jquery 插件中$.extend调用的差异?,jquery,jquery-plugins,Jquery,Jquery Plugins,我相信这个问题与此有关:谁能回答这个问题,谁就可能回答这个问题 我注意到关于jQuery的一些东西,如果我将我的插件称为: $('.view_title_images').prodigal({width: 500}); $('.glglg').prodigal({ width: 600 }); 然后,在我的init函数中,我扩展了: options = $.extend({}, options, opts); 并将其添加到每个元素:$(this).data('prodigal',optio
$('.view_title_images').prodigal({width: 500});
$('.glglg').prodigal({ width: 600 });
然后,在我的init
函数中,我扩展了:
options = $.extend({}, options, opts);
并将其添加到每个元素:$(this).data('prodigal',options)
,在选择器中。稍后,当我调用另一个函数时,在元素的上单击打开,我会得到每个元素的正确宽度值(500
,另一个600
)
但是,如果我这样做:
options = $.extend(options, opts);
对于这两个选择器,尽管分别调用,但我得到600
。我通过在我的open
函数中执行以下操作来测试这一点:
console.log($(this).data('prodigal'));
我知道不扩展到空对象将覆盖该选择器/全局对象的对象,但为什么会在每个选择器的数据上发生这种情况?首先,它是一个对象,而不是数组。您很可能不想扩展先前存在的对象,而是创建一个基于默认值的新对象,然后使用传递的选项覆盖这些对象,如下所示:
options = $.extend({}, defaults, opts);
$.extend
所做的是将第一个参数(数组或对象)与其余参数一起扩展。因此,将预先存在的对象作为第一个参数传递不会创建克隆,而是会更改原始对象
在上面的示例中,通过传递一个新对象({}
),我们创建了第二个参数的克隆,然后用第三个参数覆盖它
更改此选项将解决很多问题,但您仍可能遇到竞争条件,因为它仍将在实例之间共享相同的options对象。那么,如果我只想更改其中一个或两个实例的选项,该怎么办
解决方案很简单,只需将该行移动到。每个循环和插件的每个实例都有自己的选项对象
这是一个。首先,它是一个对象,不是数组。您很可能不想扩展先前存在的对象,而是创建一个基于默认值的新对象,然后使用传递的选项覆盖这些对象,如下所示:
options = $.extend({}, defaults, opts);
$.extend
所做的是将第一个参数(数组或对象)与其余参数一起扩展。因此,将预先存在的对象作为第一个参数传递不会创建克隆,而是会更改原始对象
在上面的示例中,通过传递一个新对象({}
),我们创建了第二个参数的克隆,然后用第三个参数覆盖它
更改此选项将解决很多问题,但您仍可能遇到竞争条件,因为它仍将在实例之间共享相同的options对象。那么,如果我只想更改其中一个或两个实例的选项,该怎么办
解决方案很简单,只需将该行移动到。每个循环和插件的每个实例都有自己的选项对象
这里有一个。尽管@Marcus的答案很好,而且它显示了插件的良好设置,实际上可以避免这种混淆,但我认为我应该放置这个答案,因为它只是更好地回答了这个问题
我在这里看到了一个用于内存管理的写时拷贝场景,就像在PHP中一样:在这里,我的init函数(如本文中所示)会受到每个调用所引用的静态选项对象的影响。因此,两者:
$('.view_title_images').prodigal({width: 500});
$('.glglg').prodigal({ width: 600 });
为插件中的选项
对象引用内存中的相同位置,因为数据分配不是写时复制安全的:
$(this).data('prodigal', options).on('click', open);
这是可以证明的,因为如果您将小提琴中的这一行更改为:
$(this).data('prodigal', $.extend(options, opts)).on('click', open);
它实际上与var options=$.extend({},options,opts)的工作原理相同代码>,它将复制到扩展上的一个新空对象,而在写入时复制该对象将触发复制
这就是我看到这一点的原因,因为每个元素中的数据
实际上是对静态对象(插件)选项
对象的引用
作为补充说明,我在发布此答案后很快发现了这一点:作者声明:
有几件事会让人们对Javascript产生误解。一个是,将布尔值或字符串指定给变量会生成该值的副本,而将数组或对象指定给变量会引用该值
这很好地解释了我的问题。尽管@Marcus的答案很好,而且它显示了插件的良好设置,实际上可以避免这种混淆,但我认为我应该放置这个答案,因为它只是更好地回答了这个问题
我在这里看到了一个用于内存管理的写时拷贝场景,就像在PHP中一样:在这里,我的init函数(如本文中所示)会受到每个调用所引用的静态选项对象的影响。因此,两者:
$('.view_title_images').prodigal({width: 500});
$('.glglg').prodigal({ width: 600 });
为插件中的选项
对象引用内存中的相同位置,因为数据分配不是写时复制安全的:
$(this).data('prodigal', options).on('click', open);
这是可以证明的,因为如果您将小提琴中的这一行更改为:
$(this).data('prodigal', $.extend(options, opts)).on('click', open);
它实际上与var options=$.extend({},options,opts)的工作原理相同代码>,它将复制到扩展上的一个新空对象,而在写入时复制该对象将触发复制
这就是我看到这一点的原因,因为每个元素中的数据
实际上是对静态对象(插件)选项
对象的引用
作为补充说明,我在发布此答案后很快发现了这一点:作者声明:
有几件事会让人们对Javascript产生误解。一个是,将布尔值或字符串指定给变量会生成该值的副本,而将数组或对象指定给变量会引用该值
这很好地解释了我的问题。“否则,您将只是更改先前存在的选项。”