1. 我们知道 jQuery 有全局变量 jQuery 和 $.
同理, zepto 也有全局变量 Zepto 和 $:
JavaScript 代码
- var Zepto;
- Windows.Zepto = Zepto;
- Windows.$ === undefined && (Windows.$ = Zepto);
从上面可以看出 zepto 的防冲突的解决方法, 是看 $ 有没有被占用.
被占了, 我就不用 $ 变量了. 所以其并没有 Zepto.noConflict 之类的方法.
2. 而全局变量 Zepto, 应该是个函数, 不然 $('div'), 怎么会用括号来运行呢?
JavaScript 代码
- var Zepto = (function() {
- var $ = function(selector, context) {};
- return $;
- })();
3. 因为函数是对象, 所以在 $ 上挂载一些工具方法也是没问题的, 比如:
JavaScript 代码
- var Zepto = (function() {
- var $ = function(selector, context) {};
- $.isWindow = function(obj) {
- return obj != null && obj == obj.Windows;
- };
- return $;
- })();
4. 因为我们知道 $('div')应该是个对象, 不然怎么使用 each 之类的方法. 所以有:
JavaScript 代码
- var Zepto = (function() {
- var $ = function(selector, context) {
- return new zepto.init(selector, context);
- };
- var zepto = {
- init: function(selector, context) {}
- };
- return $;
- })();
5. 由于 $ 的入口功能太多, zepto 跟 jQuery 一样又做了几层委托:
JavaScript 代码
- var Zepto = (function() {
- var $ = function(selector, context) {
- return zepto.init(selector, context);
- };
- var zepto = {
- init: function(selector, context) {
- //...
- return zepto.Z(dom, selector);
- },
- Z: function(dom, selector) {
- return new Z(dom, selector);
- }
- };
- var Z = function(dom, selector) {};
- return $;
- })();
6. 因为最后返回的是 Z 的实例, 那么 each 之类的实例方法应该放在 Z.prototype 上才对:
JavaScript 代码
- var Zepto = (function() {
- var $ = function(selector, context) {
- return zepto.init(selector, context);
- };
- var zepto = {
- init: function(selector, context) {
- //...
- return zepto.Z(dom, selector);
- },
- Z: function(dom, selector) {
- return new Z(dom, selector);
- }
- };
- var Z = function(dom, selector) {};
- var prototype = {
- each: function() {},
- map: function() {}
- };
- Z.prototype = prototype;
- return $;
- })();
7. 而我们平时拓展插件, 都是在 $.fn 上做的. 当然 each 也是在 $.fn 上的, 所以有:
JavaScript 代码
- var Zepto = (function() {
- var $ = function(selector, context) {
- return zepto.init(selector, context);
- };
- var zepto = {
- init: function(selector, context) {
- //...
- return zepto.Z(dom, selector);
- },
- Z: function(dom, selector) {
- return new Z(dom, selector);
- }
- };
- var Z = function(dom, selector) {};
- $.fn = {
- each: function() {},
- map: function() {}
- };
- Z.prototype = $.fn;
- return $;
- })();
8. 因为经常会遇到需要判断给定的参数是否是 Zepto 实例的情形, 所以需要个方法 isZ:
JavaScript 代码
- var Zepto = (function() {
- var $ = function(selector, context) {
- return zepto.init(selector, context);
- };
- var zepto = {
- init: function(selector, context) {
- //...
- return zepto.Z(dom, selector);
- },
- Z: function(dom, selector) {
- return new Z(dom, selector);
- },
- isZ: function(object) {
- return object instanceof Z;
- }
- };
- var Z = function(dom, selector) {};
- $.fn = {
- each: function() {},
- map: function() {}
- };
- Z.prototype = $.fn;
- return $;
- })();
但是很奇怪, 其源码没有用 object instanceof Z, 而是 zepto.Z.
因为 instanceof 的判断原理是, 看后者 (函数) 的 prototype 是否在前者 (对象) 的原型链上.
所以也要把 zepto.Z 的原型指向 Z 的原型:
JavaScript 代码
- var Zepto = (function() {
- var $ = function(selector, context) {
- return zepto.init(selector, context);
- };
- var zepto = {
- init: function(selector, context) {
- //...
- return zepto.Z(dom, selector);
- },
- Z: function(dom, selector) {
- return new Z(dom, selector);
- },
- isZ: function(object) {
- return object instanceof zepto.Z;
- }
- };
- var Z = function(dom, selector) {};
- $.fn = {
- each: function() {},
- map: function() {}
- };
- zepto.Z.prototype = Z.prototype = $.fn;
- return $;
- })();
10. 上面都是不完全推理, 也许事实并不是那么样的, 可能会有其他原因. 比如 "封装" 的用途.
我们做到能看懂就行了. 但同时也要知道用稳妥作用域的方式就可以解决上面的问题.
JavaScript 代码
- var $ = function(selector, context) {
- if (!(this instanceof $)) {
- return new $(selector, context);
- }
- // ...
- };
- $.fn = $.prototype = {
- each: function() {},
- map: function() {}
- };
- $.isWindow = function(obj) {
- return obj != null && obj == obj.Windows;
- };
本文完.
来源: http://www.qdfuns.com/article/17398/c310e7eed3fbf23b5dd1ec20eb98d37b.html