.each() 函数中的 $.extend(),奇怪的行为?

Posted

技术标签:

【中文标题】.each() 函数中的 $.extend(),奇怪的行为?【英文标题】:$.extend() in .each() function, strange behavior? 【发布时间】:2012-02-06 12:03:01 【问题描述】:

这是我作为 Highcharts api 包装器的插件的结尾。我在each() 函数中使用extend() 将属性chart.renderTo 设置为当前对象id 属性。

但是这是行不通的。 console.log($(this).attr('id')) 的输出是正确的,但 console.log(opt.chartOptions) 仅将最后一个 id (chart2) 显示为 chart.renderTo 属性。

我是否缺少关于 $.extend() jQuery 函数的内容?

    var chartOptions = ; // Plain option object

    return this.each(function()  // Each div

        console.log($(this).attr('id')); // Output: "chart1", "chart2"
        $.extend(opt.chartOptions,  chart : renderTo : $(this).attr('id')  );
        console.log(opt.chartOptions); // Ops! chart.renderTo is always "chart2"

        $.ajax(
            url : opt.url,
            type : 'POST',
            data : opt.data,
            dataType : 'json',
            success : function(data) 
                $.extend(data, opt.chartOptions); // Merge data from server
                new Highcharts.Chart(data);
            
        );

    );

【问题讨论】:

【参考方案1】:

我假设opt.chartOptions 是一个在您的插件函数中本地作用域的变量。如果这是真的,那么您在这里所做的是尝试为包装器上下文中的每个 divs 扩展 opt.chartOptions

每次迭代扩展(例如$.extend(foo,bar))时,jQuery 都会使用bar 的属性扩展foo。我相信你知道这一点。

您可能缺少的是,在您的情况下,bar 始终是 chart : 形式的对象。长话短说,.each() 的每次迭代都会覆盖之前的 $.extend() 调用。

通过第一次迭代,opts.chartOptions 将扩展为 opts.chartOptions.chart,这是根据您的 .each() 上下文中的第一个 div 计算得出的。

通过第二次迭代,您将尝试使用opts.chartOptions.chart 再次扩展opts.chartOptions它已经拥有。但是 jQuery 并不关心,所以它会将第二个 div 的计算值分配给 opts.chartOptions.chart 中的第一个 div 的值。

等等,等等。

虽然您在此处使用它的方式,它通常 不重要,因为您在 AJAX 的回调函数中使用了 opts.chartOptions 的值。这会在opts.chartOptions 上创建一个闭包,这意味着当您的 AJAX 回调触发时,它的值可能不是您所期望的(因为它可能已被 @987654342 的另一个迭代修改@,等等等等)。

哇!!

【讨论】:

以上是关于.each() 函数中的 $.extend(),奇怪的行为?的主要内容,如果未能解决你的问题,请参考以下文章

jquery函数的2种方式定义,扩展extend函数调用

$.each 和 jQuery.inArray 函数组合的奇怪输出

jquery插件模式中this和this.each有什么区别?

Scss 基本使用 ( @extend @mixin@import@if@for@while@each )

jQuery开发插件的两个方法 js 深浅拷贝

奇/偶递归函数中的分段错误