lodash工具方法(三)

lodash的工具方法(三)

_.toArray(value)

將value轉換成一個數組。javascript

/**
 * @example
 *
 * _.toArray({ 'a': 1, 'b': 2 });
 * // => [1, 2]
 *
 * _.toArray('abc');
 * // => ['a', 'b', 'c']
 *
 * _.toArray(1);
 * // => []
 *
 * _.toArray(null);
 * // => []
 */
function toArray(value) {
  if (!value) {
    return [];
  }
  if (isArrayLike(value)) {
    return isString(value) ? stringToArray(value) : copyArray(value);
  }
  if (iteratorSymbol && value[iteratorSymbol]) {
    return iteratorToArray(value[iteratorSymbol]());
  }
  var tag = getTag(value),
      func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);

  return func(value);
}

1.isArrayLike,字符串也是能夠經過這個判斷的。因此內部又判斷是不是字符串。
2。字符串的話,調用stringToArray。字符串中有區分了Unicode從而調用不一樣不一樣的方法來換成數組。java

function stringToArray(string) {
  return hasUnicode(string)
    ? unicodeToArray(string)
    : asciiToArray(string);
}

3.數組的話,調用copyArray,一目瞭然。遍歷source,將source中的元素copy到array中並返回數組

function copyArray(source, array) {
  var index = -1,
      length = source.length;

  array || (array = Array(length));
  while (++index < length) {
    array[index] = source[index];
  }
  return array;
}

4.到了iteratorSymbol&& value[iteratorSymbol]安全

在這裏,咱們先補充一點Symbol.iterator的知識工具

Symbol.iterator 爲每個對象定義了默認的迭代器。該迭代器能夠被 for...of 循環使用。Array,TypedArray,String,Map,Set具備默認的迭代器行爲。this

//默認的迭代器行爲
var myIterable = {}
yield 1;
yield 2;
yield 3;

};
[...myIterable] // [1, 2, 3]spa

瞭解了上邊的相關知識,iteratorToArray就很容易理解了。prototype

/**
* terator.next() 返回的是一個對象{value: xxx,done:false | true}
* 若是done爲true證實已經結束
*/
function iteratorToArray(iterator) {
  var data,
      result = [];

  while (!(data = iterator.next()).done) {
    result.push(data.value);
  }
  return result;
}

5.其它的邏輯code

var tag = getTag(value),
      func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
  return func(value);
  
  /**
 * Converts `set` to an array of its values.
 * 將set轉換成values數組。
 * @private
 * @param {Object} set The set to convert.
 * @returns {Array} Returns the values.
 */
function setToArray(set) {
  var index = -1,
      result = Array(set.size); // 獲取set的長度

  set.forEach(function(value) {
    result[++index] = value; // 長度push到result的數組裏
  });
  return result;
}

function values(object) {
    // keys方法,獲取可列舉的屬性(非prototype)
  return object ? baseValues(object, keys(object)) : [];
}
// 獲取object對應key上的值,,並返回
function baseValues(object, props) {
  return arrayMap(props, function(key) {
    return object[key];
  });
}

_.toPlainObject

轉換 value 爲普通對象。 包括繼承的可枚舉屬性。
/**
 * @returns {Object} Returns the converted plain object.
 * @example
 *
 * function Foo() {
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.assign({ 'a': 1 }, new Foo);
 * // => { 'a': 1, 'b': 2 }
 *
 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
 * // => { 'a': 1, 'b': 2, 'c': 3 }
 */
function toPlainObject(value) {
  
  return copyObject(value, keysIn(value));
}

copyObject咱們在baseAssign中有過描述。它將value的keys,copy到第三個參數object上。(object不在就會返回一個新的對象)orm

keysIn

/**
 * Creates an array of the own and inherited enumerable property names of `object`.
 * 建立一個數組成員爲自身的屬性,或者繼承的可枚舉的屬性。
 * **Note:** Non-object values are coerced to objects. 非對象會被強制轉換爲對象
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.keysIn(new Foo);
 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
 */
function keysIn(object) {
  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);// 類數組和不一樣的走兩種。
}

lodash對於arraylike,首先不是數組,而且value。length大於等於0,小於 Number.MAX_SAFE_INTEGER.

若是是類數組,會調用arrayLikeKeys(object, true)返回keys。非類數組調用baseKeysIn

arrayLikeKeys

/**
 * Creates an array of the enumerable property names of the array-like `value`.
 * 建立並返回一個數組。成員是類數組屬性名。
 * @private
 * @param {*} value The value to query.
 * @param {boolean} inherited Specify returning inherited property names.
 * @returns {Array} Returns the array of property names.
 */
function arrayLikeKeys(value, inherited) {
  // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
  // Safari 9 makes `arguments.length` enumerable in strict mode.
  /*數組等格式,經過baseTimes,返回一個數組,經過string轉換成字符串["0","1",...]*/
  var result = (isArray(value) || isArguments(value))
    ? baseTimes(value.length, String)
    : [];

  var length = result.length,
      skipIndexes = !!length;
 // value數組狀況下,這裏爲true,isIndex一般返回true,不會走到push這裏 || value字符串這裏爲false,,isIndex一般返回false。,字符串會走到push這裏。
  for (var key in value) {
  // case0 -若是是繼承 或者 這個,value沒有key這個屬性。
  // case1 - key不能是length屬性,好比argument有length這個屬性,是不能push到返回的。 
  // isIndex返回它是不是一個類數組的key,若是是就須要返回的。
    if ((inherited || hasOwnProperty.call(value, key)) &&
        !(skipIndexes && (key == 'length' || isIndex(key, length)))) {
      result.push(key);
    }
  }
  return result;
}
// - 這裏調用時,iteratee使用的是String,將n轉成字符串類型
function baseTimes(n, iteratee) { // n若是爲4,iteratee => String,  => ["0","1","2","3"]
  var index = -1,
      result = Array(n);

  while (++index < n) {
    result[index] = iteratee(index);
  }
  return result;
}
/**
* value是不是一個有效的array-like的index
*/
function isIndex(value, length) {
  length = length == null ? MAX_SAFE_INTEGER : length;
  return !!length &&
    (typeof value == 'number' || reIsUint.test(value)) &&
    (value > -1 && value % 1 == 0 && value < length);
}
// (typeof value == 'number' || reIsUint.test(value))   value必須是number 或者"012313"這種。
//(value > -1 && value % 1 == 0 && value < length) value必須是大於-1的整數,並且要小於length。

baseKeysIn

/**
 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
 *   `_.keysIn`的基本實現,它不將稀疏數組視爲密集。
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */
 
function baseKeysIn(object) {
  if (!isObject(object)) {
    return nativeKeysIn(object);
  }
  var isProto = isPrototype(object),
      result = [];

  for (var key in object) {
    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { // key若是是'constructor'這裏避免,自身有了一個本身定義的constructor,只有這種狀況下,咱們會返回constructor
      result.push(key);
    }
  }
  return result;
}

這裏的if判斷相對簡單些。key等於constructor這種狀況,咱們要排除自身未重寫這個屬性。

以下,會返回

function Foo() {
     this.a = 1;
    this.b = 2;
    this.constructor=3;
  }
Foo.prototype.c = 3;

(function (){
  console.log(keysIn(
    new Foo()
  ))
})()
// => Array(4) ["a", "b", "constructor", "c"]

_.toString

將value轉成字符串。若是value是null或者undefined返回空字符串。-0 將被轉換爲字符串"-0"。
/**
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {string} Returns the string.
 * @example
 *
 * _.toString(null);
 * // => ''
 *
 * _.toString(-0);
 * // => '-0'
 *
 * _.toString([1, 2, 3]);
 * // => '1,2,3'
 */
function toString(value) {
  return value == null ? '' : baseToString(value);
}

baseString

該方法是_.baseString的基礎實現,它不會將nullish值轉換爲空字符串。

function baseToString(value) {
  // Exit early for strings to avoid a performance hit in some environments.
  if (typeof value == 'string') {
    return value;
  }
  if (isSymbol(value)) {
    return symbolToString ? symbolToString.call(value) : '';
  }
  var result = (value + ''); // 對象 =>[object object], [1,2,3] => "1,2,3"
  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}

(result == '0' && (1 / value) == -INFINITY) ? '-0' : result;,容許-0,只value爲-0時,返回-0,其它狀況返回result = value + ''

_.toSafeInteger(value)

轉換 value 爲安全整數。 安全整數能夠用於比較和準確的表示。

function toSafeInteger(value) {
  return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
}

baseClamp

The base implementation of _.clamp which doesn't coerce arguments.

該方法對number的最大值最小值設定了範圍,超出就返回邊界值。

function baseClamp(number, lower, upper) {
  if (number === number) { // not NaN
    if (upper !== undefined) { //
      number = number <= upper ? number : upper;
    }
    if (lower !== undefined) {
      number = number >= lower ? number : lower;
    }
  }
  return number;
}
相關文章
相關標籤/搜索