The title

Js to achieve infinite accumulation

add(1) add(1)(2) add(1)(2)(3)

function add(. args) {
  const fn = function(. fn_args) {
      return add.apply(null, [...args, ...fn_args])
  }
  fn.toString = function() {
      return args.reduce((res, cur) = > (res + cur))
  }
  return fn
}

+ add(1) / / 1
+ add(1.2) / / 3
+ add(1) (2) (3) / / 6
Copy the code

Another way to do it

function curry(fn) {
  let allArgs = []
  return function tmp(. args) {
    if (args.length) {
      allArgs = [...allArgs, ...args]
      return tmp
    } else {
      const res = fn.apply(null, allArgs)
      allArgs = []
      return res
    }
  }
}

function add(. args) {
  return args.reduce((res, cur) = > (res + cur))
}

const addFn = curry(add)

addFn(1) ()/ / 1
addFn(1.2) ()/ / 3
addFn(1) (2.3) ()/ / 6
addFn(1) (2.3) (4) ()/ / 10
Copy the code

concept

Object.tostring () returns a string representing the object.

Object.valueof () returns the original valueOf the specified object.

ToString and valueOf methods can be overridden

The return valueOf the valueOf() method for different types of objects

object The return value
Array Returns the array object itself.
Boolean Boolean value.
Date The stored time is millisecond UTC from midnight on January 1, 1970.
Function The function itself.
Number A numeric value.
Object The object itself. This is the default.
String String value.
Math and Error objects do not have valueOf methods.

Reference: toString valueOf Typeof Instanceof Basic types

use

Object.tostring () determines the type

function getType(obj) {
    const str = Object.prototype.toString.call(obj)
    const map = {
        '[object Boolean]': 'boolean'.'[object Number]': 'number'.'[object String]': 'string'.'[object Function]': 'function'.'[object Array]': 'array'.'[object Date]': 'date'.'[object RegExp]': 'regExp'.'[object Undefined]': 'undefined'.'[object Null]': 'null'.'[object Object]': 'object'.'[object Map]': 'map'.'[object Set]': 'set'
    }
    return map[str]
}

function getType(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1).toLowercase()
}

function isType(obj, t) {
    return Object.prototype.toString.call(obj).slice(8, -1).toLowercase() === t.toLowercase()
}
Copy the code

Compare the typeof instanceof

typeof

Commonly used to judge the basic types of string/number/Boolean/symbol/bigint and function

typeof null= = ='object' // This has been true since the beginning of JavaScript
Copy the code
typeof The return value
Undefined “undefined”
Null “object”
Boolean “boolean”
Number “number”
BigInt(new in ECMAScript 2020) “bigint”
String “string”
Symbol (new in ECMAScript 2015) “symbol”
Function object (implemented according to ecMA-262 specification [[Call]]) “function”
Any other object “object”
Host object (provided by the JS environment) It depends on the implementation
instanceof

obj instanceof Object

Checks whether the constructor’s Prototype property appears in the prototype chain of an instance object

class O {
    constructor(){}}class A extends O {}
const a = new A()

a instanceof A // true
a instanceof O // true
Copy the code

Instanceof easy implementation

__proto__(.__proto__....) === A.prototype
function _instanceof(a, A) {
    const F = A.prototype
    let obj = a.__proto__
    
    while(true) {
        if (obj === null) {
            return false
        }
        if (obj === F) {
            return true
        }
        obj = obj.__proto__
    }
}
Copy the code

Type conversion – Object to primitive type

The built-in [[ToPrimitive]] function is called when the object is converted.

You can override symbol.toprimitive, which has the highest priority when going to a primitive type. ToPrimitive)

For this function, the algorithm logic is generally as follows:

  • If it is already a primitive type, no conversion is required
  • Call Object.valueof (), which returns the converted value if converted to the underlying type
  • Call Object.toString (), which returns the converted value if converted to the underlying type
  • If none of them return the primitive type, an error is reported
const a = {
  valueOf() {
    return 1
  },
  toString() {
    return '2'
  }
}

+ a / / 1
1 + a / / 2
1 > a // false
1 == a // true
1 === a // false
Copy the code

Extension: Equality judgment

There are four equality algorithms in ES2015:

  • Abstract (non-strict) equality comparison (==)
  • Strictly equal comparison (= = =) : used in the Array. The prototype. IndexOf, Array. The prototype. The lastIndexOf, and case – matching
  • With the value zero: used for % TypedArray % and ArrayBuffer constructor, and the Map and Set operation, and will be used for String of ES2016 / ES7. Prototype. Includes
  • Same value: used for all other places

JavaScript provides three different value comparison operations:

  • === strictly equal comparison
  • == Abstract equality comparison
  • Object.is