被引用到的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| // Shortcut function for checking if an object has a given property directly // on itself (in other words, not on a prototype). function has(obj, key) { return obj != null && hasOwnProperty.call(obj, key); } // Is a given variable an object? function isObject(obj) { var type = typeof obj; return type === 'function' || type === 'object' && !!obj; } // Retrieve the names of an object's own properties. function keys(obj) { if(!isObject(obj)) return []; if(Object.keys) return Object.keys(obj); var keys = []; for (var key in obj) if(has(obj, key)) keys.push(key); return keys; } // Returns the first index on an array-like that passes a predicate test function findIndex(array, fn){ var length = array != null ? array.length : 0; for (var i = 0; i < length; i++) { if (fn(array[i], i, array)) return i; } return -1; } // Returns the first key on an object that passes a predicate test function findKey(obj, fn){ var keys = keys(obj), key; for (var i = 0, length = keys.length; i < length; i++) { key = keys[i]; if (fn(obj[key], key, obj)) return key; } }
|
闭包
整个函数在一个闭包中,避免污染全局变量。通过传入this(其实就是window对象)来改变函数的作用域。
1
| (function(){ ... }.call(this))
|
格式
1 2 3 4 5
| var nativeIsArray = Array.isArray, nativeKeys = Object.keys, nativeBind = FuncProto.bind, nativeCreate = Object.create;
|
这种定义的方式省略了多余的var,格式也美观
数据判断
判断是否为dom,dom的nodeType属性值为1。这里用!!强转为boolean值
1 2 3
| function isElement(obj) { return !!(obj && obj.nodeType === 1); };
|
判断是否为数组。所以为了兼容之前的版本,在原生判断函数不存在的情况下,后面重写了一个判断函数。用call函数来改变作用域可以避免当obj没有toString函数报错的情况。
1 2 3
| isArray = Array.isArray || function(obj) { return toString.call(obj) === '[object Array]'; };
|
判断是否为对象。先用typeof判断数据类型。函数也属于对象,但是由于typeof null也是object,所以用!!obj来区分这种情况。
1 2 3 4
| isObject = function(obj) { var type = typeof obj; return type === 'function' || type === 'object' && !!obj; };
|
判断是否为arguments,很简单,arguments有个特有属性callee。
1 2 3
| isArguments = function(obj) { return has(obj, 'callee'); };
|
NaN这个值有两个特点:1.它是一个数;2.不等于它自己。
‘+’放在变量前面一般作用是把后面的变量变成一个数,在这里已经判断为一个数仍加上’+’,是为了把var num = new Number()这种没有值的数字也归为NaN。
1 2 3 4 5 6 7
| isNumber = function(obj) { return Object.prototype.toString.call(obj) === '[object ' + isNumber + ']'; }; isNaN = function(obj) { return isNumber(obj) && obj !== +obj; };
|
var b = new Boolean()。b也是布尔值。
1 2 3
| isBoolean = function(obj) { return obj === true || obj === false || Object.prototype.toString.call(obj) === '[object Boolean]'; };
|
用void 0来表示undefined,非常有意思的小技巧。
1 2 3
| isUndefined = function(obj) { return obj === void 0; };
|
Return the first value which passes a truth test.
1 2 3 4 5 6 7 8 9
| function find(obj, fn) { var key; if (obj.length === +obj.length) { key = findIndex(obj, fn); } else { key = findKey(obj, fn); } if (key !== void 0 && key !== -1) return obj[key]; }
|
noop
noop仅仅是一个空函数。因为函数不写返回值,可以是返回undefined。
1 2 3 4 5 6 7 8
| var a ; undefined = 2; if(a === undefined){ alert("2222"); } if(a===_.noop()){ alert("2222"); }
|
es3下,undefined是可以修改的,所以ie第一个alert是不执行的。这样通过函数执行可以拿到undefined的.
random
1 2 3 4 5 6 7
| _.random = function(min,max){ if(max == null){ max = min; min = 0; } return min + Math.floor(Math.random()*(max - min + 1)); };
|
uniqueId
生成dom的id
1 2 3 4 5
| var idCounter = 0; _.uniqueId = function(prefix){ var id = ++idCounter + '';//转为字符串格式 return prefix ? prefix + id :id; };
|