javascript - knockout js observable extensions 的执行顺序是什么?

标签 javascript knockout.js

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- inObject.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/

相关文章:

javascript - 将 Rails 变量传递给 JavaScript

javascript - Canvas Kineticjs - 鼠标位置错误

使用 Knockout.js 选择()输入字段

knockout.js - 使用knockoutjs过滤剑道网格的正确方法是什么?

javascript - 尝试使用 Knockout ViewModel 实现 SignalR

javascript - 从一个页面移动到另一个页面会产生错误(重复?)

javascript - 在图层中找到特定的组并重绘它

javascript - 带 Handlebars 的 #each 之外的变量

javascript - 在评估 computed() 时调用的依赖可观察对象

javascript - 在 Knockout.js 模型中创建项目之间的关系