文章目录
  1. 1. 闭包
  2. 2. 格式
  3. 3. 数据判断
  4. 4. noop
  5. 5. random
  6. 6. uniqueId

被引用到的函数

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

1
_.noop = function(){};

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;
};

文章目录
  1. 1. 闭包
  2. 2. 格式
  3. 3. 数据判断
  4. 4. noop
  5. 5. random
  6. 6. uniqueId