【问题标题】:Purpose of _.extend/_.assign?_.extend/_.assign 的目的?
【发布时间】:2014-07-17 14:50:00
【问题描述】:

我看过不少教程或代码示例,其中开发人员使用 Underscore 的 _.extend 方法或 Lodash 的 _.assign 方法,而只需添加属性就足够了,我总是感到困惑,有什么好处使用扩展/分配而不是简单地添加属性?有很多时候,我可以看到使用这些方法的好处,例如从另一个对象添加多个属性时,但我经常看到它在下面的示例中使用,但我没有看到任何好处。

以下代码是否有我不知道的好处而不是分配属性?

http://tech.pro/tutorial/1734/building-decoupled-javascript-applications-with-postaljs

var Weather = function() {
   this.channel = postal.channel( "weather" );
   this.channel.subscribe( "fetch", this.fetch ).withContext( this );
};

_.extend(Weather.prototype, {
 fetch: function( city ) {
     $.ajax({
         url: "http://openweathermap.org/data/2.1/find/name?q=" + city + "&units=imperial",
         dataType: "jsonp",
         success: _.bind(function( data ) {
             this.channel.publish( "fetched", data.list[ 0 ] );
         }, this )
     });
   }
});

比如上面的代码就不能这样重写吗:

Weather.prototype.fetch = function(...){...}

或者对此有负面影响?

【问题讨论】:

  • 这可能只是一个成语,使用相同的样式将一个属性添加为多个。
  • 这是有道理的,也是我的想法,我想确认我没有错过一些与性能或错误相关的好处。
  • 我会第二个成语; _.extend(Weather.prototype... 的读取方式与它所做的完全一样,扩展了 Weather 对象的原型
  • @Mathletics 唯一的问题是没有为 JS/ES 定义“扩展”术语。而对于其他命令式语言,它意味着不同的东西。
  • @zerkms 对于第一点,这就是为什么extend 在这么多附加库中定义的原因。其次,您是指扩展类与扩展原型之间的区别吗?

标签: javascript underscore.js lodash


【解决方案1】:

它存在的原因与 jQuery 具有 $.extend(包括 npm port)的原因相同,它与性能无关:将一个对象的属性添加到另一个对象,从而与另一个对象扩展。 Lodash' version 允许使用 customizer 函数对合并过程进行更细粒度的控制。

扩展对象有多种用途,其中一个由 jQuery 开发人员在writing plugins 上说明:

我们可以并且应该对上述代码进行的改进是公开默认插件设置。这很重要,因为它使插件用户很容易用最少的代码覆盖/自定义插件。这就是我们开始利用函数对象的地方。

// Plugin definition.
$.fn.hilight = function( options ) {

    // Extend our default options with those provided.
    // Note that the first argument to extend is an empty
    // object – this is to keep from overriding our "defaults" object.
    var opts = $.extend( {}, $.fn.hilight.defaults, options );

    // Our plugin implementation code goes here.

};

// Plugin defaults – added as a property on our plugin function.
$.fn.hilight.defaults = {
    foreground: "red",
    background: "yellow"
};

在上面的示例中,您可以清楚地看到 with 正在处理具有属性的预设对象,该对象需要扩展甚至被具有未知属性的未知对象覆盖,因为该对象超出了插件开发人员的控制


有时我们根本不知道扩展对象上有哪些属性,有时它只是使事情更具可读性,有时手动执行它很麻烦,尤其是在您需要深度合并时。

另一个应用程序是您要模拟简单继承层次结构的地方:

// very trivial example:
var Super = { superFoo: function() {} };
var Sub1 =   { sub1Foo:   function() {} };
var Sub2 =   { sub2Foo:   function() {} };

$.extend(Sub1, Super) // now Sub1 has Super powers
$.extend(Sub2, Super) // now Sub2 has Super powers too

【讨论】:

    【解决方案2】:

    在许多情况下,使用Object.assign()(或库提供的等价物)可以让人们以更实用的风格进行编写。您可以在一个大表达式中完成所有操作,而不是使用多个语句来为对象添加单个属性。

    程序:

    function doThing(options) {
        options.x = 5;
        return _doThing(options);
    }
    

    功能:

    function doThing(options) {
        _doThing(Object.assign(options, {x: 5}));
    }
    

    此外,如果与空对象一起使用,它惯用地创建一个浅拷贝,以免干扰传入的对象,从而使调用者感到困惑:

    function doThing(options) {
        _doThing(Object.assign({}, options, {x: 5}));
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-02
      • 2012-04-24
      • 2018-09-02
      • 2021-11-27
      • 1970-01-01
      相关资源
      最近更新 更多