extend 方法在js框架中的设计
2012-03-11 12:48
232 查看
今天来分析下extend方法在各种js框架下的设计。这个函数的功能基本都是实现对象的拷贝功能,即将一个对象的所有属属性拷贝到另外一个对象上去,这个函数使用的频率也很高,如果我们要将一个类的所有方法拷贝到另外方法上去,使用这个方法很方便的。
1)在百度tangram js 框架中的实现,
baidu.extend =baidu.object.extend = function (target, source) { for (var p in source) { if (source.hasOwnProperty(p)) { target[p] = source[p]; } } return target;};仅有2个参数,extend(target,source),第一个参数是目标对象,第二个参数是原对象 ,对原对象中的每个属性进行判断,如果是,那么将他拷贝到目标的对象上去。
2)在jquery 中的实现:
jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; //如果第一个值为bool值,那么就将第二个参数作为目标参数,同时目标参数从2开始计数 if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // 当目标参数不是object 或者不是函数的时候,设置成object类型的 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } //如果extend只有一个函数的时候,那么将跳出后面的操作 if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // 仅处理不是 null/undefined values if ( (options = arguments[ i ]) != null ) { // 扩展options对象 for ( name in options ) { src = target[ name ]; copy = options[ name ]; // 如果目标对象和要拷贝的对象是恒相等的话,那就执行下一个循环。 if ( target === copy ) { continue; } // 如果我们拷贝的对象是一个对象或者数组的话 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } //不删除目标对象,将目标对象和原对象重新拷贝一份出来。 target[ name ] = jQuery.extend( deep, clone, copy ); // 如果options[name]的不为空,那么将拷贝到目标对象上去。 } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // 返回修改的目标对象 return target;};
jquery的实现原理和tangram差不多,也是讲原对象的属性分别拷贝到目标对象上去,不过jq可以接受的参数比tangram要多,他可以接受无限和参数,如果第一个参数为true的话,将执行深度拷贝,将原对象和目标对象中的某些属性值合并起来。
3)protype.js的实现方式
function extend(destination, source) { for (var property in source) destination[property] = source[property]; return destination; }
也是遍历原 对象的各种属性,然后将他拷贝到目标对象上去。实现的方式和tangram类似。
4)dojo的实现
dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){ // summary: // Adds all properties and methods of props to constructor's // prototype, making them available to all instances created with // constructor. for(var i=1, l=arguments.length; i<l; i++){ d._mixin(constructor.prototype, arguments[i]); } return constructor; // Object }
var extraNames, extraLen, empty = {}; for(var i in {toString: 1}){ extraNames = []; break; } dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "constructor"]; extraLen = extraNames.length; dojo._mixin = function(/*Object*/ target, /*Object*/ source){ // summary: // Adds all properties and methods of source to target. This addition // is "prototype extension safe", so that instances of objects // will not pass along prototype defaults. var name, s, i; for(name in source){ // the "tobj" condition avoid copying properties in "source" // inherited from Object.prototype. For example, if target has a custom // toString() method, don't overwrite it with the toString() method // that source inherited from Object.prototype s = source[name]; //fixed by yupeng 判断元素是否是对象的属性 if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){ target[name] = s; } } // IE doesn't recognize some custom functions in for..in if(extraLen && source){ for(i = 0; i < extraLen; ++i){ name = extraNames[i]; s = source[name]; if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){ target[name] = s; } } } return target; // Object }
dojo首先会封装一个_mixin方法,该方法起到的作用其实就是extend该起到的作用,然后再背部调用_mixin()方法,封装的extend方法可以接受多个参数,同时将原对象的每个属性都拷贝到目标对象的原型方法上。
技巧(extend方法的妙用):
1)实现组件参数的灵活配置,我们在写组件的时候,可以使用一些默认的配置参数,但是如果用户想定制一些特殊的样式的话,可以使用extend方法
例如在写jq插件的时候
(function($) { $.fn.xxxx= function(options) {
var defaults = { a: false, b: {}, c: false, b: false }; var params = $.extend({}, defaults, options || {});
//接下来对函数进行处理。
}
})(jquery)
2)实现类方法的拷贝。
1)在百度tangram js 框架中的实现,
baidu.extend =baidu.object.extend = function (target, source) { for (var p in source) { if (source.hasOwnProperty(p)) { target[p] = source[p]; } } return target;};仅有2个参数,extend(target,source),第一个参数是目标对象,第二个参数是原对象 ,对原对象中的每个属性进行判断,如果是,那么将他拷贝到目标的对象上去。
2)在jquery 中的实现:
jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; //如果第一个值为bool值,那么就将第二个参数作为目标参数,同时目标参数从2开始计数 if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // 当目标参数不是object 或者不是函数的时候,设置成object类型的 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } //如果extend只有一个函数的时候,那么将跳出后面的操作 if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // 仅处理不是 null/undefined values if ( (options = arguments[ i ]) != null ) { // 扩展options对象 for ( name in options ) { src = target[ name ]; copy = options[ name ]; // 如果目标对象和要拷贝的对象是恒相等的话,那就执行下一个循环。 if ( target === copy ) { continue; } // 如果我们拷贝的对象是一个对象或者数组的话 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } //不删除目标对象,将目标对象和原对象重新拷贝一份出来。 target[ name ] = jQuery.extend( deep, clone, copy ); // 如果options[name]的不为空,那么将拷贝到目标对象上去。 } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // 返回修改的目标对象 return target;};
jquery的实现原理和tangram差不多,也是讲原对象的属性分别拷贝到目标对象上去,不过jq可以接受的参数比tangram要多,他可以接受无限和参数,如果第一个参数为true的话,将执行深度拷贝,将原对象和目标对象中的某些属性值合并起来。
3)protype.js的实现方式
function extend(destination, source) { for (var property in source) destination[property] = source[property]; return destination; }
也是遍历原 对象的各种属性,然后将他拷贝到目标对象上去。实现的方式和tangram类似。
4)dojo的实现
dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){ // summary: // Adds all properties and methods of props to constructor's // prototype, making them available to all instances created with // constructor. for(var i=1, l=arguments.length; i<l; i++){ d._mixin(constructor.prototype, arguments[i]); } return constructor; // Object }
var extraNames, extraLen, empty = {}; for(var i in {toString: 1}){ extraNames = []; break; } dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "constructor"]; extraLen = extraNames.length; dojo._mixin = function(/*Object*/ target, /*Object*/ source){ // summary: // Adds all properties and methods of source to target. This addition // is "prototype extension safe", so that instances of objects // will not pass along prototype defaults. var name, s, i; for(name in source){ // the "tobj" condition avoid copying properties in "source" // inherited from Object.prototype. For example, if target has a custom // toString() method, don't overwrite it with the toString() method // that source inherited from Object.prototype s = source[name]; //fixed by yupeng 判断元素是否是对象的属性 if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){ target[name] = s; } } // IE doesn't recognize some custom functions in for..in if(extraLen && source){ for(i = 0; i < extraLen; ++i){ name = extraNames[i]; s = source[name]; if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){ target[name] = s; } } } return target; // Object }
dojo首先会封装一个_mixin方法,该方法起到的作用其实就是extend该起到的作用,然后再背部调用_mixin()方法,封装的extend方法可以接受多个参数,同时将原对象的每个属性都拷贝到目标对象的原型方法上。
技巧(extend方法的妙用):
1)实现组件参数的灵活配置,我们在写组件的时候,可以使用一些默认的配置参数,但是如果用户想定制一些特殊的样式的话,可以使用extend方法
例如在写jq插件的时候
(function($) { $.fn.xxxx= function(options) {
var defaults = { a: false, b: {}, c: false, b: false }; var params = $.extend({}, defaults, options || {});
//接下来对函数进行处理。
}
})(jquery)
2)实现类方法的拷贝。
相关文章推荐
- extend 方法在js框架中的设计
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)
- Android应用 程序框架设计方法
- 非常实用的js验证框架实现源码 附原理方法
- JS框架设计之主流框架的引入机制DomeReady一种子模块
- js如何实现设计模式中的模板方法
- php ci框架中加载css和js文件失败的原因及解决方法
- Node.js Express 框架 GET方法
- JS的location.href跳出框架打开新页面的方法
- JS框架设计之对象数组化一种子模块
- 使用anguarjs TemplateUI框架方法
- JS刷新框架中的其他页面&&JS刷新窗口方法汇总
- js对象或类的方法设计模式解读
- JQuery选取器与其它JS框架冲突的解决方法 确保jQuery不会与其他库的$对象发生冲突
- android学习笔记---53_采用网页设计软件界面,以及使用android系统内置的浏览器,利用js调用java方法
- jsp Iframe框架下,跨框架 访问 js 方法
- js框架之间应用方法
- 子框架页面链接改变(js方法)
- JS框架设计之命名空间设计一种子模块
- Js-$.extend扩展方法使方法参数更灵活