首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Javascript设计模式 - 笔记1

富有表现力的javascript

弱类型语言

javascript中有三种原始类型:布尔型、数值型(不区分浮点数和整数)和字符串型。

此外,还有对象类型和包含可执行代码的函数类型。前者是一种复合类型(数组是一种特殊的对象)。

最后,还有空类型(null)和未定义类型(undefined)。

原始数据类型按值传送,其他数据类型则按引用传送。

函数是一等对象

  • 匿名函数

1 2 3 4 5

(function(){ var foo = 10; var bar = 2; alert(foo * bar); })();

  • 闭包

1 2 3 4 5 6 7 8 9

var baz; (function(){ var foo = 10; var bar = 2; baz = function(){ return foo * bar; } })(); baz(); //baz可以访问foo和bar,即使是在匿名函数外面执行

  • 作用域、嵌套函数和闭包
    • js中,只有函数具有作用域: 在一个函数内部声明的变量,外部无法访问; 定义在一个函数中的变量在该函数的内嵌函数中是可以访问的
    • js中的作用域是词法性的: 函数运行在定义他们的作用域中,而不是调用他们的作用域中; 可以利用这个特性定义静态方法和属性;

对象的易变性(mutable)和内省(introspection)

  • 易变性:js中可以对象前定义的类和实例化的对象进行修改
  • 内省:js中可以在运行时检查对象所具有的属性和方法

接口

  • 接口也是一种对象,判断一个类是否是实现了某类接口,就是传入这个接口,而后比较。 java有专门的接口类,C++有虚基类,而C在linux kernel中的对象设计方法实际上也是一种接口实现,这都是接口在语言层面支持的体现
  • 封装(encapsulation)和信息隐藏:信息隐藏是目的,而封装则是藉以达到这个目的的技术 java和C++有 private关键字作为支持,Python有’__‘的命名约定,js中一般用闭包来模拟

接口实现

用注释来模拟

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

/* interface Composite { function add(child); function remove(child); ... } interface FormItem{ function save(); } var CompositeForm = function(id, method, action) { //implements Composite, FromItem ... }; CompositeForm.prototype.add = function(child) { ... } CompositeForm.prototype.remove= function(child) { ... } CompositeForm.prototype.save= function() { ... }

  • 优点:简单明了,代码体积小
  • 缺点:无法错误检查

用属性检查模仿接口

约定所有类明确声明实现了那些接口,和这些类打交道的对象可以针对这些声明做检查。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

/* interface Composite { function add(child); function remove(child); ... } interface FormItem{ function save(); } var CompositeForm = function(id, method, action) { //implements Composite, FromItem this.implementsInterfaces = ['Composite', 'FromItem']; ... }; ... function addForm(formInstance) { if (!implements(formInstance, 'Composite', 'FormItem')) { throw new Error("object does not implement a required interface"); } } function implements(objects) { for (var i = 1; i < arguments.length; i++) { var interfaceName = arguments[i]; var interfaceFound = false; for (var j = 0; j < object.implementsInterfaces[j] == interfaceName) { interfaceFound = true; break; } if (!interfaceFound) { return false; } } return true; }

  • 优点:有错误检查
  • 缺点:每次调用都要检查,啰嗦,另外防不住有说了实现但没有干活的

鸭式辨型模仿接口

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

var Composite = new Intreface('Composite', ['add', 'remove']); var FormItem = new Interface('FormItem', ['save']); var CompositeForm = function(id, method, action) { ... }; function addForm(formInstance) { ensureImplements(formInstance, Composite, FormItem); ...... } var Interface = function(name, methods) { if (arguments.length != 2) { throw new Error("Interface constructor called with " + arguments.length + "arguments, but expected exactly 2."); } this.name = name; this.methods = []; for (var i = 0; len = methods.length; i < len; i++) { if (typeof methods[i] !== 'string') { throw new Error("Interface contructor expects method names to be " + "passed in as string"); } } this.methods.push(methods[i]); } Interface.ensureImplements = function(object) { if (arguments.length < 2) { throw Error("Functino Interface.ensureImplements called with " + arguments.length + "arguments, but expected at leaset 2."); } for (var i = 1, len = arguments.length; i < len; i++) { if (interface.constructor !== Interface) { throw new Error("Function Interface.ensureImplements expects arguments" + "two and above to be instances of Interface."); } } for (var j = 1, methodsLen = interface.methods.length; j < methodsLen; j++) { var method = interface.methods[j]; if(!object[method] || typeof object[method] !== 'function') { throw new Error("Function Interface.ensureImplements: object " + "does not implement the " + interface.name) + "interface.Method " + method + " was not found."); } } }

  • 优点:进一步加强了错误检查
  • 缺点:增大了调试难度
下一篇
举报
领券