据说每个大牛、小牛都应该有自己的库——框架篇中我扬言要做个小牛,没想到一天没更新,小伙儿伴们就戏谑的问我,油哥是不是要太监了?其实事情是这个样子的,这不是太监的节奏,一是,关于写个自己的库的想法由来已久,但只是周末才下决心要写,本来觉得会有很多以前的总结要写出来的,可是一下笔才知道有多难,零零散散的东西谁都能够写出来,可怎么把这些东西写的有条理、效率高、可用性强之前从来没有想过,二是最近几天和未来的日子公司会比较忙,下班回来的时间有限,没太多时间去想,所以拖沓了,不过不会太监。

JavaScript原生对象

言归正传要想对JavaScript原生对象进行拓展,首先得了解JavaScript究竟有哪些原生对象,《JavaScript语言精髓与编程实践》上有一张广为流传的图片

内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始化阶段就被创建好的对象,是后者的一个子集;而后者包括了一些在运行过程中动态创建的对象。宿主对象不是引擎的原生对象,而是由宿主框架通过某种机制注册到JavaScript引擎中的对象。

这么多原生对象,并不是每个都要拓展,只是拓展一下在其它语言中存在的,用起来很方便的方法,至于拓展方式也很简单,无非是向prototype里面注册。

两个原则

在反复写了很多通用函数后我总是在试图解决使用者可能的疏忽,比如在为某个元素绑定click事件处理程序的时候,我要先判断用户传的元素是否为空,是的话直接返回false;判断click是不是写成了onclick;判断欲绑定的函数是不是个函数。。。,这样的工作确实使库函数更加好使,但带来了几个显著的弊端

1.层层判断,效率低下,相信这点儿不用多说明

2.为了使函数不报错而返回false,自己处理了异常,没有把错误显示返回给用户,难以发现错误及调试

3.纵容了使用的的不良行为

权衡了一下,在自己的库函数中不会帮助使用者处理参数及使用错误,如果出现错误不处理,直接返回给使用者。

但是很多函数并不要求用户传入所有参数,比如jQuery的ajax函数,可以传入部分参数,不传入部分按默认值处理,这是合理的,库函数中也会遵守这一原则。

String

对String对象的拓展主要有

  • ltrim:去除string左边空白符
  • rtrim:去除string右边空白符
  • trim:去除string首尾空白符
  • htmlEncode:把html字符串encode成普通字符串
  • htmlDecode:把字符串decode为html字符串
  • isStartsWith:判断字符串是否以参数开始
  • isEndWith:判断字符串是否以参数结束
if(typeof String.prototype.ltrim=='undefined'){
String.prototype.ltrim = function(){
var s = this;
s = s.replace(/^\s*/g, '');
return s;
}
} if(typeof String.prototype.rtrim=='undefined'){
String.prototype.rtrim = function(){
var s = this;
s = s.replace(/\s*$/g, '');
return s;
}
} if(typeof String.prototype.trim=='undefined'){
String.prototype.trim = function(){
return this.ltrim().rtrim();
}
} if(typeof String.prototype.htmlEncode=='undefined'){
String.prototype.htmlEncode = function(encodeNewLine){//encodeNewLine:是否encode换行符
var s = this;
s = s.replace(/&/g, '&');
s = s.replace(/</g, '&lt;');
s = s.replace(/>/g, '&gt;');
s = s.replace(/'/g, '&quot;');
if(encodeNewLine){
s = s.replace(/\r\n/g, '<br />');
s = s.replace(/\r/g, '<br />');
s = s.replace(/\n/g, '<br />');
}
return s;
}
} if(typeof String.prototype.htmlDecode=='undefined'){
String.prototype.htmlDecode = function(decodeNewLine){//decodeNewLine:是否decode换行符
var s = this;
if(decodeNewLine)
{
s = s.replace(/<br\s*\/?>/gi, '\r\n');
}
s = s.replace(/&quot;/g, '\'');
s = s.replace(/&gt;/g, '>');
s = s.replace(/&lt;/g, '<');
s = s.replace(/&amp;/g, '&');
return s;
}
} if(typeof String.prototype.startsWith=='undefined'){
String.prototype.startsWith = function(start, ignoreCase){//start:欲判断字符, ignoreCase:是否忽略大小写
var s = this;
if(ignoreCase)
{
s = s.toLowerCase();
end = end.toLowerCase();
}
if(s.substr(0, start.length) == start)
return true;
return false;
}
} if(typeof String.prototype.endsWith=='undefined'){
String.prototype.endsWith = function(end, ignoreCase){//end:欲判断字符, ignoreCase:是否忽略大小写
var s = this;
if(ignoreCase)
{
s = s.toLowerCase();
end = end.toLowerCase();
}
if(s.substr(s.length - end.length) == end)
return true;
return false;
}
}

Array

对Array对象的拓展有

  • indexOf:返回参数在数组中index,不存在返回-1
if(typeof Array.prototype.indexOf=='undefined'){
Array.prototype.indexOf=function(item,strict){//strict:是否严格相等(===)
var index=-1;
var strict=strict=='undefined'? true || strict;
var length=this.length;
if(strict){
for(var i=0;i<length;i++){
if(this[i]===item){
index=i;
break;
}
}
}else{
for(var i=0;i<length;i++){
if(this[i]==item){
index=i;
break;
}
}
}
}
}

Date

Date对象的拓展

format:格式化日期(网上找的,据说是个老外写的,但是找不到作者)

getDaysInMonth:获取某月有多少天

Date.getDaysInMonth = function (year, month) {
var days = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
days = 29;
else
days = 28;
break;
}
return days;
} if (typeof Date.prototype.format == 'undefined') {
Date.prototype.format = function (mask) { var d = this; var zeroize = function (value, length) { if (!length) length = 2; value = String(value); for (var i = 0, zeros = ''; i < (length - value.length); i++) { zeros += '0'; } return zeros + value; }; return mask.replace(/"[^"]*"|'[^']*'|\b(?:d{1,4}|m{1,4}|yy(?:yy)?|([hHMstT])\1?|[lLZ])\b/g, function ($0) { switch ($0) { case 'd': return d.getDate(); case 'dd': return zeroize(d.getDate()); case 'ddd': return ['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'][d.getDay()]; case 'dddd': return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][d.getDay()]; case 'M': return d.getMonth() + 1; case 'MM': return zeroize(d.getMonth() + 1); case 'MMM': return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][d.getMonth()]; case 'MMMM': return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][d.getMonth()]; case 'yy': return String(d.getFullYear()).substr(2); case 'yyyy': return d.getFullYear(); case 'h': return d.getHours() % 12 || 12; case 'hh': return zeroize(d.getHours() % 12 || 12); case 'H': return d.getHours(); case 'HH': return zeroize(d.getHours()); case 'm': return d.getMinutes(); case 'mm': return zeroize(d.getMinutes()); case 's': return d.getSeconds(); case 'ss': return zeroize(d.getSeconds()); case 'l': return zeroize(d.getMilliseconds(), 3); case 'L': var m = d.getMilliseconds(); if (m > 99) m = Math.round(m / 10); return zeroize(m); case 'tt': return d.getHours() < 12 ? 'am' : 'pm'; case 'TT': return d.getHours() < 12 ? 'AM' : 'PM'; case 'Z': return d.toUTCString().match(/[A-Z]+$/); // Return quoted strings with the surrounding quotes removed default: return $0.substr(1, $0.length - 2); } }); };
}

最后

开始时会以为要写很多,筛选了一下,常用并且通用还需要自己拓展的无非就这几个,很没有成就感的样子,不过还好总算没太监不是,以后想到再补充吧,这两天要好好想想关于Event处理的函数了。

最近听取了一下朋友的意见,对JavaScript原生对象进行拓展确实是个很鸡肋的事情,决定把JavaScript原生对象部分单独拿出来成一个文件,想使用的话需要引用的页面,不再库函数中默认包含。

据说每个大牛、小牛都应该有自己的库——JavaScript原生对象拓展的更多相关文章

  1. 据说每个大牛、小牛都应该有自己的库——DOM处理续

    在上篇据说每个大牛.小牛都应该有自己的库——DOM处理最后剩下attr()和css()方法没有处理,因为这两个方法当时并不自计划中,是写着写着突然想到的,一时间没有特别好的思路,当时已十一点多了,就去 ...

  2. 据说每个大牛、小牛都应该有自己的库——DOM处理

    这几天整理了一下思路,本来觉得DOM部分会有很多东西,但是忽然发现频繁使用的其实并不太多 class class处理部分主要有四个 hasClass:检查元素是否包含某个class addClass: ...

  3. 据说每个大牛、小牛都应该有自己的库——Ajax

    蹉跎到今天终于要写Ajax部分了,平时工作中除了选择器我用jQuery的最多的就是ajax,所以这部分在自己的框架中必不可少. XMLHttpRequest 我以为对每个使用过Ajax的人来说XMLH ...

  4. 据说每个大牛、小牛都应该有自己的库——Event处理

    今天抽时间写了一部分Event处理方面的函数愈发的觉得jQuery的优秀,自己前期的想法太粗糙,造成后面这些函数参数很多,操作很很不直观,看样子是要重构的节奏,还好小伙儿伴们安慰,架构都是改出来的.继 ...

  5. Object类 任何类都是object类的子类 用object对象接收数组 object类的向上向下转型

    任何类都是object类的子类 用object对象接收数组 object类的向上向下转型

  6. JS事件 什么是事件?JavaScript 创建动态页面。事件是可以被 JavaScript 侦测到的行为。 网页中的每个元素都可以产生某些可以触发 JavaScript 函数或程序的事件。

    什么是事件 JavaScript 创建动态页面.事件是可以被 JavaScript 侦测到的行为. 网页中的每个元素都可以产生某些可以触发 JavaScript 函数或程序的事件. 比如说,当用户单击 ...

  7. 让所有网站都提供API的Python库:Toapi

    这是一个让所有网站都提供API的Python库.以前,我们爬取数据,然后把数据存起来,再创造一个api服务以便其他人可以访问.为此,我们还要定期更新我们的数据.这个库让这一切变得容易起来.你要做的就是 ...

  8. Xcode 5.1 编译模拟器以及真机都能使用的静态库

    Xcode 5.1.dmg 下载地址 http://pan.baidu.com/s/1jGJpKm6 1.新建 Framework & Library 工程 我起名叫ShowInfo,下面为其 ...

  9. 99.9%的Java程序员都说不清的问题:JVM中的对象内存布局?

    本文转载自公众号:石彬的架构笔记,阅读大约需要8分钟. 作者:李瑞杰 目前就职于阿里巴巴,资深 JVM 研究人员 在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我 ...

随机推荐

  1. tomcat使用线程池配置高并发连接

    1:配置executor属性打开/conf/server.xml文件,在Connector之前配置一个线程池:[html] view plain copy<Executor name=" ...

  2. 分享个win平台cocos2d-x创建项目的快捷方式

    由于长期使用vs开发,相信使用vs开发的同学们也和我一样,都习惯点击图标然后就新建项目了,不是很适应命令的方式 由于vs2012一般都是win7 win8 win8.1这类系统开发,而这些系统,都是自 ...

  3. awk 的一些用法

    awk,我觉得是Linux里面处理文本最精妙的命令,它是一个行处理的命令,它最初级的用法是:给定一些简单的pattern,然后按照这个pattern 去搜索匹配的行.它的高级用法是用awk来编程,除了 ...

  4. java jdk动态代理

    在面试的时候面试题里有一道jdk的动态代理是原理,并给一个事例直接写代码出来,现在再整理一下 jdk动态代理主要是想动态在代码中增加一些功能,不影响现有代码,实现动态代理需要做如下几个操作 1.首先必 ...

  5. padding(内边距)、margin(外边距)、border(边框)

    元素的 padding 控制元素内容 content和元素边框 border 之间的距离. 元素的外边距 margin 控制元素边框 border 和元素实际所占空间的距离,如果你将一个元素的 mar ...

  6. 使用 AForge.NET 做视频采集

    AForge.NET 是基于C#设计的,在计算机视觉和人工智能方向拥有很强大功能的框架.btw... it's an open source framework. 附上官网地址: http://www ...

  7. C#学习之Stream

    上节课老师主要讲了stream及其一些运用和实例,下面我们就来讨论讨论Stream. 我们知道,C#中常用的stream有文件流(FileSteam),内存流(MemoryStream),压缩流(GZ ...

  8. vs2010中的MSBuild输出warning MSB8012问题

    vs2010中,MSBuild与C++编译器无缝整合.无论使用vs2010生成的代码,还是转换vs2008或者是更低版本vs编译的C++代码.都会在工程编译后,都会提示一条错误: C:\Program ...

  9. linux之LVM

    一.简介 LVM是逻辑盘卷管理(Logical Volume Manager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵 ...

  10. Code::Blocks配置GTK+2和GTK+3

    Code::Blocks配置GTK+2和GTK+3 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根 ...