Research on source code of underscore.js (4)

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324781603&siteId=291194637