在 extending observables 的 knockoutjs 文档底部它指出...
More than one extender can be applied in a single call to the .extend method of an observable.
this.firstName = ko.observable(first).extend({ required: "Please enter a first name", logChange: "first name" });
In this case, both the required and logChange extenders would be executed against our observable.
...我想知道扩展将以什么顺序执行。它总是以相同的顺序执行吗?什么定义了顺序?
最佳答案
顺序在当前的 Knockout(撰写本文时为 3.4.0)中未定义,因为 JavaScript 对象属性在 ES2015 之前没有定义顺序,甚至在 ES2015 中,for- in
和 Object.keys
没有顺序。
当前的 Knockout 像这样循环通过这些扩展器:
function applyExtenders(requestedExtenders) {
var target = this;
if (requestedExtenders) {
ko.utils.objectForEach(requestedExtenders, function(key, value) {
var extenderHandler = ko.extenders[key];
if (typeof extenderHandler == 'function') {
target = extenderHandler(target, value) || target;
}
});
}
return target;
}
它的objectForEach
函数使用了for-in
:
function objectForEach(obj, action) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
action(prop, obj[prop]);
}
}
}
因此,在当前的 Knockout 中,没有定义扩展程序运行的顺序(即使在 ES2015 上)。
理论上,Knockout 的 future 版本可以使用新的 Object.getOwnPropertyNames
相反:
function applyExtenders(requestedExtenders) {
var target = this;
if (requestedExtenders) {
Object.getOwnPropertyNames(requestedExtenders).forEach(function(key) {
var extenderHandler = ko.extenders[key];
if (typeof extenderHandler == 'function') {
target = extenderHandler(target, requestedExtenders[key]) || target;
}
});
}
return target;
}
getOwnPropertyNames
遵循新定义的 JavaScript 属性顺序,列在 §9.1.12 中的规范。在您的示例中,这将是 required
,然后是 logChange
,因为对象初始值设定项按词法顺序创建属性,而名称不全的“自己”属性的顺序 - numeric 而不是 Symbol
是创建的顺序(但请参阅规范了解详细信息)。
关于javascript - knockout js observable extensions 的执行顺序是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36330717/