UNPKG

image2d

Version:

🍇 使用ECMAScript绘制二维图片。Drawing Two-Dimensional Pictures Using ECMAScript.

127 lines (112 loc) 4.21 kB
/** * 设计需求是: * image2D和image2D(selector[, context]) * 分别表示绘图类和绘图对象 * * 题外:为什么不选择image2D和new image2D(selector[, context])? * 只是感觉没有前面的写法用起来简洁 * * 为了实现需求,第一反应是: * let image2D=function(selector,context){ * return new image2D(); * }; * * 在image2D上挂载静态方法,在image2D.prototype上挂载对象方法, * 看起来稳的很,其实这明显是一个死循环。 * * 为了解决这个问题,我们在image2D的原型上定义了一个方法: * image2D.prototype.init=function(selector,context){ * return this; * }; * * 执行下面的方法: * let temp=image2D.prototype.init(selector, context); * 上面返回的temp很明显就是image2D.prototype,其实就是image2D对象 * (例如:new A(),其实就是取A.prototype,这样对比就很好理解了) * * 因此可以改造代码如下: * * 这样image2D和new image2D(selector[, context])就分别表示类和对象。 * * 问:看起来是不是实现了? * 答:是的,实现了。 * 问:可是总感觉有点不好,说不出为什么。 * 答:是不是感觉image2D()打印出来的东西有点多? * 问:是的。 * * 事实上,因为直接取image2D.prototype作为new image2D(), * 理论上说,使用上区别不大,唯一不足的是, * 挂载在image2D.prototype上的方法会在打印image2D对象的时候看见,不舒服。 * * 为了看起来好看些,代码再次改造: * let image2D = function (selector, context) { * return new image2D.prototype.init(selector, context); * }; * * 为了让image2D(selector, context)返回的是image2D对象,需要修改image2D.prototype.init的原型: * image2D.prototype.init.prototype = image2D.prototype; * * 这样: * image2D(selector, context) == * return new image2D.prototype.init(selector, context) == * image2D.prototype.init.prototype == * image2D.prototype == * new image2D(selector, context) * * 此时需求就实现了, * 而且打印image2D(selector, context)的时候, * 对象上的方法都在原型上,看起来就比较舒服了。 */ import sizzle from '../core/sizzle'; import { isObject } from '@hai2007/tool/type'; let image2D = function (selector, context) { return new image2D.prototype.init(selector, context); }; image2D.prototype.init = function (selector, context) { // 如果没有传递,默认使用document作为上下文 this.context = context = context || document; // 使用sizzle获取需要维护的结点,并把结点维护到image2D对象中 let nodes = sizzle(selector, context), flag; for (flag = 0; flag < nodes.length; flag++) { this[flag] = nodes[flag]; } // 设置结点个数 this.length = nodes.length; return this; }; // 扩展方法 // 在image2D和image2D.prototype上分别调用extend方法就可以在类和对象上扩展方法了 image2D.prototype.extend = image2D.extend = function () { var target = arguments[0] || {}; var source = arguments[1] || {}; var length = arguments.length; /* * 确定复制目标和源 */ if (length === 1) { //如果只有一个参数,目标对象是自己 source = target; target = this; } if (!isObject(target)) { //如果目标不是对象或函数,则初始化为空对象 target = {}; } /* * 复制属性到对象上面 */ for (let key in source) { try { target[key] = source[key]; } catch (e) { // 为什么需要try{}catch(e){}? // 一些对象的特殊属性不允许覆盖,比如name // 执行:image2D.extend({'name':'新名称'}) // 会抛出TypeError throw new Error("Illegal property key:" + key + "!"); } } return target; }; image2D.prototype.init.prototype = image2D.prototype; export default image2D;