Overview
I have wanted to study the underscore source code for a long time. Although the underscore.js library is a bit outdated, I still want to learn about the library's architecture, functional programming and the writing of common methods, but there is nothing else to study. , so let's end the wish to study the underscore source code.
underscore.js source code research (1)
underscore.js source code research (2)
underscore.js source code research (3)
underscore.js source code research (4)
underscore.js source code research (5)
underscore.js source code research (6)
underscore. js source code research (7)
underscore.js source code research (8)
References: official notes of underscore.js , undersercore source code analysis , undersercore source code analysis segmentfault
Type judgment
For type judgment, most elements can be judged by the result of Object.prototype.toString , including: Arguments, Function, String, Number, Date, RegExp, Symbol, Map, WeakMap, Set, WeakSet. Examples are as follows:
//判断是否为函数,判断其他的只要把下面的Function改成其它的就可以了
function isFunction (obj) {
return Object.prototype.toString.call(obj) === '[object Function]';
}
//建立一个函数
var haha = function haha() {
consolog.log('haha');
}
console.log(isFunction(haha)); //输出true
console.log(isFunction(123)); //输出false
Note that the previous versions of IE9 and the early V8 engine have some small bugs in type judgment , underscore.js fixes these problems, you can check the underscore.js source code for details .
isElement
To determine whether it is a DOM node, use the nodeType property :
function isElement(obj) {
return !!(obj && obj.nodeType === 1);
}
isArray
To judge whether it is an array, use Array.isArray first , if not, use Object.prototype.toString
var isArray = Array.isArray || function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
isObject
Use typeof to determine whether it is an object.
function isObject(obj) {
var type = typeof obj;
return type === 'function' || type ==='object' && !!obj;
}
As you can see, functions are judged as objects, and empty objects {}, undefined, null, NaN, etc. are not considered objects.
isFinite
Judgment is limited. It is mainly judged by using the isFinite function provided globally by js.
function isFinite(obj) {
return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj));
}
The last !isNaN(parseFloat(obj)) is to exclude bool values.
isNaN
To judge whether it is NaN, it is mainly judged by isNaN provided by js globally .
function isNaN(obj) {
return _.isNumber(obj) && isNaN(obj);
}
is Boolean
Determines whether it is a Boolean.
function isBoolean(obj) {
return obj === true || obj === false || Object.prototype.toString.call(obj) === '[object Boolean]';
}
isNull
To judge whether it is null, just judge directly.
function isNull(obj) {
return obj === null;
}
isUndefined
To determine whether it is undefined, use void 0.
function isUndefined(obj) {
return obj === void 0;
}
equality judgment
Many times we have to judge the equality of two elements. At this time, we can judge their types first, and then judge their values. There can be some special cases:
- 0 === -0
- null == undefined
- NaN! = NaN
- NaN! == NaN
Their solutions are as follows:
- 1/0 === 1/0; 1/-0 !== 1/0
- null === null; null !== undefined;
- if(a !== a) return b !== b;
I'm not going to write general comparison cases here, just a few special cases :
Regular Expressions and Strings
Mainly converted to strings and then compared
Eq = function(a, b) {
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
return '' + a === '' + b;
}
number
Need to exclude 0 and NaN cases, and use +a to convert a to a number .
Eq = function(a, b) {
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
}
date and boolean
Use +a to convert a to a number .
Eq = function(a, b) {
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
return +a === +b;
}
Symbol
Use SymbolProto.valueOf method.
Eq = function(a, b) {
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
}
Note: You cannot directly use '==' or '===' to judge the equality of objects for the following reasons:
var a = new Object();
var b = new Object();
a.name = "mm";
b.name = "mm";
console.log(a == b); //false