YUI 读码日记之 YAHOO.lang.is*[转]
2009-04-26 09:36
489 查看
作者:手气不错 发布时间:March 4, 2008 分类:Javascript
在 YUI 框架的 %BULID%/yahoo/yahoo.js 中,包含了一系列的变量类型检测方法,它们被分装成 YAHOO.lang.is* 。其中,这些函数的大部分封装都是 typeof 操作符的封装,我个人比较敢兴趣的事 isArray 与 isValue 的两个函数。
…… 复制粘贴分割线 ……
据悉,在 YUI 2.2.0 版本以前,YAHOO.lang.isArray 是这样写的。
而这样的判断数组类型是有缺陷的,比如下面的代码
因此,在 YUI 的后续版本,YAHOO.lang.isArray 被修改成了目前的这个样子
新的实现用了另外的思路:如果该对象有 length 这个属性,同时支持 splice 方法,那么就认为它为数组。当然,它依然有漏洞,我们仍然可以创建一个对象,使其拥有 length 属性和 splice 方法。但我觉得现在的实现更为合理,因为一来可能性不大,二来避免了诡异的浏览器的 BUG 。
再看 YUI 2.3.0 后引入的 YAHOO.lang.isValue,其实就是判断参数是否是一个有意义的值,只要参数不是 null/undefined/NaN,那么都返回 true。(注意这和一般的判断真假的不同就是, 0/false/''(空字符串) 这些都算是有效的值),所以 YAHOO.lang.isValue 非常适合用来判断表单域的值是否为有效值。
597 toString = Object.prototype.toString;
...
616 isArray: function(obj) {
617 return toString.call(obj) === "[object Array]";
在 YUI 框架的 %BULID%/yahoo/yahoo.js 中,包含了一系列的变量类型检测方法,它们被分装成 YAHOO.lang.is* 。其中,这些函数的大部分封装都是 typeof 操作符的封装,我个人比较敢兴趣的事 isArray 与 isValue 的两个函数。
YAHOO.lang = YAHOO.lang || { isArray: function(o) { if (o) { var l = YAHOO.lang; // 如果该对象有 length 这个属性,同时支持 splice 方法, // 那么就认为它为数组。 return l.isNumber(o.length) && l.isFunction(o.splice); } return false; }, isBoolean: function(o) { return typeof o === 'boolean'; }, isFunction: function(o) { return typeof o === 'function'; }, isNull: function(o) { return o === null; }, isNumber: function(o) { return typeof o === 'number' && isFinite(o); }, isObject: function(o) { return (o && (typeof o === 'object' || YAHOO.lang.isFunction(o))) || false; }, isString: function(o) { return typeof o === 'string'; }, isUndefined: function(o) { return typeof o === 'undefined'; }, //... isValue: function(o) { // Infinity fails // return (o || o === false || o === 0 || o === ''); var l = YAHOO.lang; return (l.isObject(o) || l.isString(o) || l.isNumber(o) || l.isBoolean(o)); } };
…… 复制粘贴分割线 ……
据悉,在 YUI 2.2.0 版本以前,YAHOO.lang.isArray 是这样写的。
isArray: function(obj) { // safari 有 bug,只好处理字符串 if (obj && obj.constructor && obj.constructor.toString().indexOf('Array') > -1) { return true; } else { return YAHOO.lang.isObject(obj) && obj.constructor == Array; } },
而这样的判断数组类型是有缺陷的,比如下面的代码
function myArray() { this.name = 'name'; } var o2 = new myArray(); alert(YAHOO.util.isArray(o2)); // 弹出true // 因为 obj.constructor.toString() 中包含 myArray 字样,所以返回true function Obj() { this.name = 'name'; } var o = new Obj(); o.constructor = Array; alert(YAHOO.util.isArray(o)); // 弹出 true // 因为在 JavaScript 里,constructor 也是属性 // 可以动态指定,所以返回 true
因此,在 YUI 的后续版本,YAHOO.lang.isArray 被修改成了目前的这个样子
isArray: function(o) { if (o) { var l = YAHOO.lang; // 如果该对象有 length 这个属性,同时支持 splice 方法, // 那么就认为它为数组。 return l.isNumber(o.length) && l.isFunction(o.splice); } return false; },
新的实现用了另外的思路:如果该对象有 length 这个属性,同时支持 splice 方法,那么就认为它为数组。当然,它依然有漏洞,我们仍然可以创建一个对象,使其拥有 length 属性和 splice 方法。但我觉得现在的实现更为合理,因为一来可能性不大,二来避免了诡异的浏览器的 BUG 。
再看 YUI 2.3.0 后引入的 YAHOO.lang.isValue,其实就是判断参数是否是一个有意义的值,只要参数不是 null/undefined/NaN,那么都返回 true。(注意这和一般的判断真假的不同就是, 0/false/''(空字符串) 这些都算是有效的值),所以 YAHOO.lang.isValue 非常适合用来判断表单域的值是否为有效值。
Javascript 对象的 toString 方法返回对象的描述信息,很多时候我们都忘记了还有这属性的存在。
在查看 jQuery 源码时,发现其 isArray 竟然令人惊艳的使用 toString 进行类型判断:597 toString = Object.prototype.toString;
...
616 isArray: function(obj) {
617 return toString.call(obj) === "[object Array]";
相关文章推荐
- YUI 读码日记之 YAHOO.lang.is*
- YUI 读码日记之 YAHOO.lang.is*
- javascript YUI 读码日记之 YAHOO.util.Dom - Part.4
- YUI 读码日记之 YAHOO.util.Dom - Part.1
- Javascript YUI 读码日记之 YAHOO.util.Dom - Part.3
- Javascript YUI 读码日记之 YAHOO.util.Dom - Part.2 0
- Javascript YUI 读码日记之 YAHOO.util.Dom - Part.2 0
- YUI 读码日记之 YAHOO.util.Dom - Part.1
- javascript YUI 读码日记之 YAHOO.util.Dom - Part.4
- JBOSS报错:Deployment "AttachmentStore" is in error due to: java.lang.IllegalArgumentException
- java.lang.IllegalArgumentException: The observer is null.终于解决方式
- mybatis报错 There is no getter for property named 'xx' in 'class java.lang.String
- [yui]Yahoo!User Interface Libray 介绍
- target is null for setProperty(null, "name", [Ljava.lang.String;@696ece)
- spring No default constructor found; nested exception is java.lang.NoSuchMethodException: com.slj.mo
- The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files
- java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.widget.CheckBox.is
- mybaits的There is no getter for property named 'id' in 'class java.lang.Integer异常
- Mybatis There is no getter for property named 'XXX' in 'class java.lang.XXX
- The type java.lang.Object cannot be resolved.It is indirectly referenced from required .class files