插件中$ .extend调用的区别? [英] Difference in $.extend calls in a plugin?
问题描述
我相信这个问题与此有关: init如何起作用工作在插件中?,谁能回答这个问题就可以回答.
I believe this question relates to this: How does the init function work in plugins? and whoever can answer this can probably answer that.
如果我这样称呼我的插件,我会注意到有关jQuery的一些信息
I noticed something about jQuery, if I call my plugin like:
$('.view_title_images').prodigal({width: 500});
$('.glglg').prodigal({ width: 600 });
然后,在我的init
函数中,我扩展为:
And then, in my init
function I extend with:
options = $.extend({}, options, opts);
并将其添加到每个元素:选择器中的$(this).data('prodigal', options)
.稍后,当我调用另一个函数,即元素的click
上的open
时,我会为每个元素获得正确的width
值(一个元素为500
,另一个元素为600
).
and add that to each element: $(this).data('prodigal', options)
in the selector. I get the correct width
value for each element (500
for one and 600
for the other) later on when I call another function, open
on the click
of the element.
但是,如果我这样做:
options = $.extend(options, opts);
对于两个选择器,尽管被分别调用,但得到的却是600
.我通过在open
函数中进行测试:
For both selectors, despite being called separately, I get 600
. I test this by doing, in my open
function:
console.log($(this).data('prodigal'));
我知道不扩展到空对象会覆盖该选择器/全局对象的对象,但是为什么这会在每个选择器的data
上发生?
I know that not extending to an empty object will override the object for that selector/global object but why is this happening on the data
of each selector?
推荐答案
即使@Marcus的答案是一个很好的选择,它显示了一个很好的插件设置,实际上可以避免这种混乱,我认为我会放置这个答案,因为可以更好地回答这个问题.
Even though @Marcus' answer is a good one and it shows a good setup to plugins that will actually avoid this confusion I thought I would place this answer because it just answers the question a little better.
我正在像在PHP中那样在此处见证用于内存管理的写时复制方案:是写时复制吗?,由此我的init函数显示在以下小提琴中: http: //jsfiddle.net/Sammaye/65XLy/1 的静态选项对象被引用到每个调用中.因此,两者:
I am witnessing, like in PHP, a copy on write scenario for memory management here: What is copy-on-write? whereby my init function, as displayed in this fiddle: http://jsfiddle.net/Sammaye/65XLy/1 suffers from the static options object being referenced to each of the calls. So both of:
$('.view_title_images').prodigal({width: 500});
$('.glglg').prodigal({ width: 600 });
为插件中的options
对象在内存中引用相同的位置,因为数据分配不是在写安全时复制的:
Reference the same position in memory for the options
object in the plugin since the data assignment is not copy on write safe:
$(this).data('prodigal', options).on('click', open);
这是可以证明的,因为如果您将小提琴中的这一行更改为:
This is proven since if you change this line in the fiddle to:
$(this).data('prodigal', $.extend(options, opts)).on('click', open);
它实际上与var options = $.extend({}, options, opts);
相同,在扩展时它确实复制到了一个新的空对象,而在写时进行复制会触发一个副本.
It actually works the same as var options = $.extend({}, options, opts);
whereby it does copy to a new empty object on extend which in copy on write would trigger a copy.
这就是为什么我看到它,因为每个元素中的data
实际上是对静态对象(插件)options
对象的引用.
That is why I am seeing this, because the data
in each of the elements is actually a reference to the static objects (plugins) options
object.
作为补充,我在发布此答案后不久便发现了这一点: http ://my.opera.com/GreyWyvern/blog/show.dml/1725165 ,其中作者指出:
As an added note I actually found this soon after posting this answer: http://my.opera.com/GreyWyvern/blog/show.dml/1725165 whereby the author states:
有一些事情使人们对Java感到厌烦.一个事实是,将布尔值或字符串分配给变量会复制该值,而将数组或对象分配给变量则会引用该值.
There are a few things that trip people up with regards to Javascript. One is the fact that assigning a boolean or string to a variable makes a copy of that value, while assigning an array or an object to a variable makes a reference to the value.
哪个可以完美地解释我的问题.
Which explains my problem perfectly.
这篇关于插件中$ .extend调用的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!