Archive for the ‘JavaScript’ Category
小知识点. (定期更新)
在使用 jQuery 绑定的事件处理函数中, return, return false, e.preventDefault, e.stopPropagation 意思.
return -> 不向下执行;
e.preventDefault() -> 禁止默认事件;
e.stopPropagation() -> 禁止事件冒泡;
return false; -> 不向下执行, 禁止默认事件, 禁止事件冒泡;
@update 2012-01-03
防止命名冲突:
(function () {})(); // 使用匿名函数.
使用命名空间.
class 可以在多个位置使用. 在 JavaScript 中使用 class 时, 注意命名空间. root.find(‘.a’); sidebar.find(‘.a’);
JavaScript 对象: Boolean, Number, String, Function, Array, Date, RegExp, Object.
@update 2012-01-06
函数式编程
ps: 在网上看到”并行性编程和元数据” 是编程的趋势.
JavaScript 中的函数:
匿名函数, 函数做为值, 函数做为参数,函数做为返回值.
from web:
函数:
函数并不总是需要名称。
函数可以像其他值一样分配给变量。
函数表达式可以编写并放在括号中,留待以后应用。
函数可以作为参数传递给其他函数。
纯函数: 唯一的输入是它的参数,唯一的输出是它的返回值.
一个不规范的函数有可能会依赖一个全局变量或一些类成员数据。在这种情况下,函数的行为并不完全决定于它的参数值.相似的,一个不规范的函数有可能会更改一个全局变量或修改数据库。这种情况下,函数除了返回值外,还会附带一些额外操作.
纯函数具有亲系透彻性(referential transparency),也就是说,针对相同的输入值,它一定给出相同的输出值。函数输出不依赖系统时间、数据库状态以及任何没有显式的作为参数传入函数的东西。这也表明纯函数易于理解(因此也易于调试和测试)。
函数式编程的基石之一:不变性(immutability)
函数式编程和过程式编程:
#函数 -> 过程: 定义解决问题的过程. 函数式: 需要描述问题是什么.
函数式编程中使用到的 curry -> http://www.jimzhan.com/blog/archives/3035.
function curry(fn){ var slice = Array.prototype.slice; var args = slice.call(arguments, 1); return function(){ var innerArgs = slice.call(arguments, 0); var allArgs = args.concat(innerArgs); return fn.apply(null, allargs); } } // @param {Function} Function.prototype.myqueue = function (fn) { var self = this; return function () { self(); fn(); }; }; Function.prototype.myqueue = function () { var slice = Array.prototype.slice; var argus = slice.call(arguments); var self = this; argus.unshift(self); return function () { for (var i = 0, max = argus.length; i < max; i++) { argus[i](); } }; };
jQuery 中的 proxy 方法:
proxy: function( fn, context ) { var args = slice.call(arguments, 2), proxy = function() { return fn.apply( context, args.concat( slice.call( arguments ) ) ); }; return proxy; }, if ( typeof context === "string" ) { var tmp = fn[ context ]; context = fn; fn = tmp; } function bind(fn, context){ return function(){ return fn.aplly(context,arguments); } }
所谓函数柯里化,在计算机科学中是指的是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数。
在读新闻时, 想到这样: 扩展内置对象方法, 但是不破坏对象 prototype. 值得思考一下.
ps: 前端开发是个无底洞啊~
更新 core 层.
之前谈过, 模块化开发, Core – Sandbox – Module
Core -> 注册/注销机制 + 消息通讯机制.
Sandbox -> 对 Module 提供 api.
Module -> 匿名函数进行独立开发.
- 支持先触发, 后注册.
[?支持性弱]
update: 2012-01-01 10: 20.
当触发事件时, 如果不存在此事件绑定, 则做记录;
当事件绑定时, 去扫描记录, 如果存在记录, 就执行处理函数, 但记录保留, 以备同时注册的同名事件使用;
当再触发已记录事件(b)时, 此时已绑定事件, 则直接执行处理函数. 此后, 再绑定同名事件时, (b) 处理函数不再执行.update: 2012-01-01 11: 22.
换个角度思考, [ps: 当前解决的问题, 它本身是用来解决什么问题的, 求的是最终问题的解决方案]. 消息通讯机制, 是为了通知各个模块界面状态 – [起始页项目如此]; 而界面状态最终肯定只有一个, 即要么a, 要么b, 不能同时a/b; 那么先触发后注册问题, 也就是记录最后状态问题; 即把最后一种 type, arguments 记录下即可.
(ps: 这个问题值得再思考] - 支持延迟加载 JavaScript 文件 [很少用户会使用的功能, 可延迟加载]
目前仅支持单个脚本.
- 扩展 notify 参数格式支持.
原 notify 时, 参数格式仅支持 单个参数 或 json 格式. 更新后的, 支持任意格式, 可以多个参数.
api.notify('event-name', 'test'); api.notify('event-name', 'a', 'b', 'c'); api.notify('event-name', {a: 'a', b: 'b'}); // 本质是一个参数.
1月份花时间会对 sandbox 层, 进行整理, 然后在不同项目中, 使用统一扩展. [即共用扩展]
2012 年, 有很多事情要做…….
- 花一定时间陪小石头, 陪她一起成长.
- 锻炼身体. 保证良好的身体才能陪小石头, 才能正常工作. 各种户外, 组内活动.
- 坚持参加交流会. 了解行业基本动向. 开拓下视野. 和朋友见见面, 聊聊天, 吃饭.
- 部门内做分享. 自己理清思路, 大家指点, 提建议. 和其它部门合作, 了解设计模式/数据结构/算法.
- 尝试在项目中使用 html5 (css3/JavaScript api);
- 提高海外组生产力. 各种节省时间工具, 充分利用现有环境.
curry JavaScript
JavaScript 函数值得去挖掘. 今天用到下面:
function proxy(a) { return function (b) { return a + b; } } var test = proxy(5); var result = test(6); console.log(result);
使用一函数生成一函数, 此函数把参数当作固定值[此参数也是通过变量传递来的]在生成的函数中使用.
后来找到相关资源, 原来叫 JavaScript Curry 化.
@update 2012-01-01 09: 33
// from 《JavaScript Patterns》 function schonfinkelize(fn) { var slice = Array.prototype.slice, stored_args = slice.call(arguments, 1); return function () { var new_argus = slice.call(arguments), argus = stored_args.concat(new_argus); return fn.apply(null, argus); }; }
@update: 2012-01-03.
jQuery 中的 proxy 使用此方法.
JavaScript api 中有新的 bind 方法.
if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== "function") { // closest thing possible to the ECMAScript 5 internal IsCallable function throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () {}, fBound = function () { return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }; }
资源:
- Google Curry JavaScript
- http://julabs.me/blog/front/curry-javascript-intro/
- http://www.svendtofte.com/code/curried_javascript/
- http://stackoverflow.com/questions/113780/javascript-curry-what-are-the-practical-applications
- http://www.dustindiaz.com/javascript-curry/
- https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
Core – Sandbox – Module 开发模式.
项目中一直在使用的开发模式 – Core-Sandbox-Module [w3ctech 交流会上有专门谈过].
- Core 核心文件, 不依赖任何库. 主要做模块注册、销毁和消息通知管理.
- Sandbox 是对 Module 开放的 api, 提供 Module 间通信接口 + app 扩展.
- Module 应用划分的模块. 可多人开发. [思考: 真的会有多个人来开发么?] – 便于模块化维护[不影响其它模块]
库[jQuery...]可以任意选择. [我们使用 jQuery - 简单. 都会写 - 虽然写的不够好 ~]
库扩展[插件]. jQuery.fn.xxx;
这些做为基础层[base]. -> 好前戏就到这里~
对于可扩展性, 库可扩展[ex: jQuery.fn.xxx -> jQuery.prototype.xxx; jQuery.xxxx;].
Core 层可扩展. [~ 昨天尝试了, 比较悲剧 ~]
Sandbox 层可扩展. -> 平时使用的比较多~, 把通用的方法挂在 Sandbox 上.
Module 层保持独立. -> 在匿名函数中, 保持孤立. 只能使用 Sandbox 提供的消息接口对向通信.
介绍模块通信:
先回顾下浏览器中的事件注册和触发. 我们是这样做的:
- 在元素上绑定事件[addEventListener];
- 用户进行操作交互[Trigger Click/Mouse 等事件];
- 触发元素上绑定的函数.
- 同时也可以移除事件绑定.[RemoveEventListener]
模块通信机制和其类似, 即在 Core 中把 传统的事件中的保存事件逻辑实现. Core 层做浏览器做的事 [提供保存空间; 提供对外事件绑定和解除绑定接口]
即, 事件注册需要在前, 否则执行默认行为[Core 层, 默认行为即什么都不做~ 或仅记录日志.]
现在问题是: 绑定事件时, 处理逻辑需要额外code, 即需要其它 Module 或者 扩展支援. 即需要一个依赖处理 和 一个 JavaScript 加载处理. 【加载器】.
下面是昨天尝试的悲剧. [思考: 对核心模块的扩展, 应该保持 Core 核心文件不变动, 把扩展加到 prototype 上即可. 好简单~ ]
打开 Core 文件后: var Core = (function () { return {};} ());
Core 是一个对象字面量, 没有 prototype; 好悲剧的事情~.
那么退一步, 把代码放到 Sandbox 扩展上, 结果是实现了~, 但是感觉代码好别扭. api.notify(‘event-name’, data});
注册时: api.listen(‘event-name’, ‘jQuery’, function () {}); 这里把需要的插件[组件] load 进来即可.
注册时: api.notify(‘proxy’, {rule: ‘event-name’, path: ‘jQuery’, callback: callback});
即使用 Sandbox 的 api 来完成本来应该在 Core 层上完成上的扩展~…
有时间更新下核心玩玩~