Welcome 微信登录

首页 / 脚本样式 / JavaScript / knockout.js源码解析

knockout.js源码解析2015-06-09

简介

本文主要对源码和内部机制做较深如的分析,基础部分请参阅官网文档。

knockout.js (以下简称 ko )是最早将 MVVM 引入到前端的重要功臣之一。目前版本已更新到 3 。相比同类主要有特点有:

双工绑定基于 observe 模式,性能高。

插件和扩展机制非常完善,无论在数据层还是展现层都能满足各种复杂的需求。

向下支持到IE6

文档、测试完备,社区较活跃。

入口

以下分析都将对照 github 上3.x的版本。有一点需要先了解:ko 使用 google closure compiler 进行压缩,因为 closure compiler 会在压缩时按一定规则改变代码本身,所以 ko 源码中有很多类似ko.exportSymbol("subscribable", ko.subscribable) 的语句来防止压缩时引用丢失。愿意深入了解的读者可以自己先去读一下 closure compiler,不了解也可以跳过。

启动代码示例:

var App = function(){this.firstName = ko.observable("Planet");this.lastName = ko.observable("Earth");this.fullName = ko.computed({read: function () {return this.firstName() + " " + this.lastName();},write: function (value) {var lastSpacePos = value.lastIndexOf(" ");if (lastSpacePos > 0) {this.firstName(value.substring(0, lastSpacePos));this.lastName(value.substring(lastSpacePos + 1));}},owner: this });} ko.applyBindings(new App,document.getElementById("ID"))
直接翻到源码 /src/subscribables/observable.js 第一行。

ko.observable = function (initialValue) {var _latestValue = initialValue; function observable() {if (arguments.length > 0) {// Write// Ignore writes if the value hasn"t changedif (observable.isDifferent(_latestValue, arguments[0])) {observable.valueWillMutate();_latestValue = arguments[0];if (DEBUG) observable._latestValue = _latestValue;observable.valueHasMutated();} return this; // Permits chained assignments}else {// Readko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operationreturn _latestValue;}}ko.subscribable.call(observable);ko.utils.setPrototypeOfOrExtend(observable, ko.observable["fn"]); if (DEBUG) observable._latestValue = _latestValue;/**这里省略了专为 closure compiler 写的语句**/<br>return observable; }