繁体   English   中英

是否可以在 Javascript 中使用方法链分配字符串?

[英]Is it possible to use method chaining assigning strings in Javascript?

我想使用 JavaScript 和 AngularJS 使用方法链语法。 我分配数组和字符串。

此代码有效:

$mdDateLocaleProvider
     .shortDays = ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá']
     .msgCalendar = 'Calendario'
;

此代码不起作用:

$mdDateLocaleProvider
     .shortDays = ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá']
     .msgCalendar = 'Calendario'
     .msgOpenCalendar = 'Abrir calendario'
;

我认为msgOpenCalendar = 'Abrir calendario'句子由于字符串分配而失败。

我的解决方案:

$mdDateLocaleProvider
     .shortDays = ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá']
     .msgCalendar = 'Calendario'
;
$mdDateLocaleProvider
     .msgOpenCalendar = 'Abrir calendario'
;

为什么分配字符串时出现问题,但分配数组时没有问题?

名称是方法链接是有原因的,它用于链接方法,而不是变量赋值。

在方法链中,您只是在方法(函数)的末尾返回对象实例(可变或新的不可变对象),因此您可以“立即”调用下一个函数。

它“作品”的原因是,在JS数组是一个对象,所以你只需放置一个msgCalendar您分配到阵列中财产shortDays财产。

基本上,你取得的是:

var shortDays = ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá'].msgCalendar = 'Calendario';
// here shortDays actually equals to 'Calendario', because it is like writing a = b = 2.
$mdDateLocaleProvider.shortDays = shortDays;
$mdDateLocaleProvider.msgOpenCalendar = 'Abrir calendario';

你不能像你正在做的那样使用直接赋值的方法链。 正如 Ron 所解释的,你认为它所做的并不是它实际在做的。

解决此问题的一种方法是实现Builder 模式,该模式允许您基于链接它们的 setter 方法来创建对象。

您不能使用链接,但是当您在问题中包含 angularjs 标签时,您可能想要查看使用angular.extend

angular.extend($mdDateLocaleProvider, {
     shortDays: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá'],
     msgCalendar: 'Calendario',
     msgOpenCalendar: 'Abrir calendario'
});

这将具有更新三个属性的预期效果,如果您想调用任何方法,您甚至可以对结果使用方法链。

你想要assign()

 Object.assign($mdDateLocaleProvider, {
      shortDays : ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá']
      msgCalendar : 'Calendario'
      msgOpenCalendar : 'Abrir calendario'
 });

这将为您立即设置一切。


如果您需要实际链接,例如可能设置shortDays ,调用一个函数,然后设置msgCalendar ,试试我的垫片。
这也适用于assign不起作用(设置 DOM onclick s 或innerText s),或者您需要调用不链接的函数。

 wrap($mdDateLocaleProvider)
      .set('shortDays'      , ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá'])
      .set('msgCalendar'    , 'Calendario')
      .set('msgOpenCalendar', 'Abrir calendario')
 ;

只需调用wrap()就可以了。

wrap = (obj) => (Object.defineProperty(obj,
            'define', {value:(name, options) => (Object.defineProperty(obj, name, options))})
    .define('assign', {value:(props)         => (Object.assign(obj, props))                })
    .define('set'   , {value:(name, value)   => { obj[name] = value; return obj; }         })
    .define('invoke', {value:(name, ...args) => { obj[name](...args); return obj; }        })
);

演示

let bob = {
    hello  : 'there',
    chains : () => {bob.I_RAN = true; return bob;},
    doesnt : (arg1, arg2) => {bob.I_RAN_ALSO = [arg1, arg2]; return null;}
};
wrap(bob)
    .set('oh', 'my')
    .chains()
    .invoke('doesnt', 'works', 'anyway')
    .assign({more:7, stuff:null})
;
for (let item of Object.keys(bob))
      console.log(`'${item}' : ${bob[item]}`);

输出:
在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM