是否可以在 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'
;
为什么分配字符串时出现问题,但分配数组时却没有?
名称为方法链接是有原因的,它用于链接方法,而不是变量赋值。
在方法链中,您只需在方法(函数)的末尾返回对象实例(可变或新的不可变对象),因此您可以调用下一个函数"right away"。
它"works"的原因是JS中的数组是一个对象,所以你只需在分配给shortDays
的数组上放置一个msgCalendar
属性 属性.
基本上,你的成就是:
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 pattern,它允许您基于链接其 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
,试试我的 shim。
这也适用于 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]}`);
输出:
我想使用 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'
;
为什么分配字符串时出现问题,但分配数组时却没有?
名称为方法链接是有原因的,它用于链接方法,而不是变量赋值。
在方法链中,您只需在方法(函数)的末尾返回对象实例(可变或新的不可变对象),因此您可以调用下一个函数"right away"。
它"works"的原因是JS中的数组是一个对象,所以你只需在分配给shortDays
的数组上放置一个msgCalendar
属性 属性.
基本上,你的成就是:
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 pattern,它允许您基于链接其 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
,试试我的 shim。
这也适用于 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]}`);
输出: