javascript当中的代码嗅探扩展原生对象和原型(prototype)


Posted in Javascript onJanuary 11, 2013

:翻译之中有什么不恰当的地方,欢迎大家指正,祝大家双节快乐!
如果不是有特殊需要而去扩展原生对象和原型(prototype)的做法是不好的

//不要这样做 
Array.prototype.map = function() { 
// 一些代码 
};

除非这样做是值得的,例如,向一些旧的浏览器中添加一些ECMAScript5中的方法。
在这种情况下,我们一般这样做:
if (!Array.prototype.map) { 
Array.prototype.map = function() { 
//一些代码 
}; 
}

如果我们比较偏执,为了防止别人将map定义为其它意想不到的值,像true或其他,我们可以 将检测代码改为下面这样:
if (typeof Array.prototype.map !== "function") { 
Array.prototype.map = function() { 
// 一些代码 
}; 
}

(尽管这将破坏其它开发者的map定义,并影响他们功能的实现)
但是,在一个充满敌意和残酷竞争的环境下(换句话说,但你提供或者使用一个js库时),你不应该相信任何人。如果其他人的js代码先于你的js代码加载,并且以某种方式定义了一个不完全兼容ES5的map()方法,导致你的代码不能正常运行,该怎么办呢?

不过,你可以相信浏览器,如果Webkit内核实现了map()方法,你可以放心,这个方法肯定会正常运行。否则的话,你就要用你的代码进行检测了。

幸运的是,这在JavaScript当中很容易实现,当你调用原生函数的toString方法的时候,会返回一个函数的字符串,该函数的函数体是[native code]。
例如在Chrome的控制台下:

> Array.prototype.map.toString(); 
"function map() { [native code] }"

一个适当的代码检查向来就是一个稍微令人不快的事,因为不同浏览器对空格和换行处理的太过轻率。测试如下:
Array.prototype.map.toString().replace(/\s/g, '*'); 
// "*function*map()*{*****[native*code]*}*" // IE 
// "function*map()*{*****[native*code]*}" // FF 
// "function*map()*{*[native*code]*}" // Chrome

只简单的去掉\s会得到更实用的字符串:
Array.prototype.map.toString().replace(/\s/g, ''); 
// "functionmap(){[nativecode]}"

你可以将它封装成一个可以重用的shim()函数,这样以来你就没有必要去重复所有的类似!

Array.prototype...这样的操作了。这个函数会接受一个对象作为参数(例如,Array.prototype),一个将要添加的属性(例如 'map')和一个要添加的函数。

function shim(o, prop, fn) { 
var nbody = "function" + prop + "(){[nativecode]}"; 
if (o.hasOwnProperty(prop) && 
o[prop].toString().replace(/\s/g, '') === nbody) { 
//表名是原生的! 
return true; 
} 
//新添加的 
o[prop] = fn; 
}

测试:
//这是原生的方法 
shim( 
Array.prototype, 'map', 
function(){/*...*/} 
); // true 
//这是新添加的方法 
shim( 
Array.prototype, 'mapzer', 
function(){alert(this)} 
); 
[1,2,3].mapzer(); // alerts 1,2,3

(完)^_^
Javascript 相关文章推荐
理解Javascript_08_函数对象
Oct 15 Javascript
jQuery实现点击标题输入详细信息
Apr 16 Javascript
通过javascript获取iframe里的值示例代码
Jun 24 Javascript
js动态修改整个页面样式达到换肤效果
May 23 Javascript
js下将阿拉伯数字每三位一逗号分隔(如:15000000转化为15,000,000)
Jun 02 Javascript
javascript实现ecshop搜索框键盘上下键切换控制
Mar 18 Javascript
Bootstrap企业网站实战项目4
Oct 14 Javascript
js 性能优化之快速响应的用户界面
Feb 15 Javascript
Angular中支持SCSS的方法
Nov 18 Javascript
jQuery插件Validation表单验证详解
May 26 jQuery
vue中对象数组去重的实现
Feb 06 Javascript
Javascript新手入门之字符串拼接与变量的应用
Dec 03 Javascript
关于JavaScript的面向对象和继承有利新手学习
Jan 11 #Javascript
不用构造函数(Constructor)new关键字也能实现JavaScript的面向对象
Jan 11 #Javascript
javascript使用中为什么10..toString()正常而10.toString()出错呢
Jan 11 #Javascript
javascript将数组插入到另一个数组中的代码
Jan 10 #Javascript
jquery实现点击TreeView文本父节点展开/折叠子节点
Jan 10 #Javascript
javascript 中String.match()与RegExp.exec()的区别说明
Jan 10 #Javascript
防止文件缓存的js代码
Jan 10 #Javascript
You might like
PHP服务器页面间跳转实现方法
2012/08/02 PHP
PHP可变函数学习小结
2015/11/29 PHP
php实现微信支付之现金红包
2018/05/30 PHP
js的with语句使用方法
2007/09/21 Javascript
js下获取div中的数据的原理分析
2010/04/07 Javascript
简略说明Javascript中的= =(等于)与= = =(全等于)区别
2013/04/16 Javascript
用javascript添加控件自定义属性解析
2013/11/25 Javascript
jQuery实现仿QQ在线客服效果的滚动层代码
2015/10/15 Javascript
jquery验证邮箱格式并显示提交按钮
2015/11/07 Javascript
JS检测移动端横竖屏的代码
2016/05/30 Javascript
详解vue.js+UEditor集成 [前后端分离项目]
2017/07/07 Javascript
动态加载权限管理模块中的Vue组件
2018/01/16 Javascript
微信小程序实现tab左右切换效果
2020/11/15 Javascript
mpvue将vue项目转换为小程序
2018/09/30 Javascript
jQuery+Datatables实现表格批量删除功能【推荐】
2018/10/24 jQuery
javascript设计模式之装饰者模式
2020/01/30 Javascript
python实现根据ip地址反向查找主机名称的方法
2015/04/29 Python
浅谈django中的认证与登录
2016/10/31 Python
详解python实现读取邮件数据并下载附件的实例
2017/08/03 Python
python实现简单神经网络算法
2018/03/10 Python
Python开发最牛逼的IDE——pycharm
2018/08/01 Python
Python实现二维曲线拟合的方法
2018/12/29 Python
Python定时发送天气预报邮件代码实例
2019/09/09 Python
Python try except异常捕获机制原理解析
2020/04/18 Python
python能开发游戏吗
2020/06/11 Python
Python如何实现远程方法调用
2020/08/07 Python
完美解决IE8下不兼容rgba()的问题
2017/03/31 HTML / CSS
美国独家设计师眼镜在线光学商店:Glasses Gallery
2017/12/28 全球购物
Christys’ Hats官网:英国帽子制造商
2018/11/28 全球购物
一套带答案的C++笔试题
2014/01/10 面试题
电教室标语
2014/06/20 职场文书
药剂专业求职信
2014/06/20 职场文书
工作总结与自我评价
2014/09/18 职场文书
2015年计生协会工作总结
2015/04/24 职场文书
windows server 2016 域环境搭建的方法步骤(图文)
2022/06/25 Servers
win sever 2022如何占用操作主机角色
2022/06/25 Servers