Interpretation of lodash source code (2)

Red plume 2021-05-04 11:05:35
interpretation lodash source code


Preface

The book follows :Lodash Source code interpretation ( One )

.internal

arrayIncludesWith

/**
* similar arrayIncludes Function of
* The difference is that you can pass in a comparison function
*
* @private
* @param {Array} [array] Array to look up
* @param {*} target The value to search for
* @param {Function} comparator Comparison function called for each element
* @returns {boolean}  If target If found, return to true Otherwise return to false
*/
function arrayIncludesWith(array, target, comparator) {
// Take advantage of JavaScript stay == The feature that automatically casts the type when the 
// It's filtered out undefined and null
if (array == null) {
return false;
}
for (const value of array) {
if (comparator(target, value)) {
return true;
}
}
return false;
}
export default arrayIncludesWith;
 Copy code 

arrayLikeKeys

import isArguments from '../isArguments.js';
import isBuffer from '../isBuffer.js';
import isIndex from './isIndex.js';
import isTypedArray from '../isTypedArray.js';
/** from Object Of prototype Pick up hasOwnProperty Used to detect the properties of the object itself */
const hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* by array-like Creates an array of enumerable property names
*
* @private
* @param {*} value The value to query
* @param {boolean} inherited Specify return inheritance ( On the prototype ) The property name
* @returns {Array}  Returns an array of enumerable property names
*/
function arrayLikeKeys(value, inherited) {
// Judge whether it is array or array-like
const isArr = Array.isArray(value);
const isArg = !isArr && isArguments(value);
const isBuff = !isArr && !isArg && isBuffer(value);
const isType = !isArr && !isArg && !isBuff && isTypedArray(value);
// If value yes array or array-like You need to collect index
const skipIndexes = isArr || isArg || isBuff || isType;
const length = value.length;
// Instantiate a new array The length is value.length Same as or equal to 0
// The length of the new array depends on value Is it array or array-like
const result = new Array(skipIndexes ? length : 0);
let index = skipIndexes ? -1 : length;
// collect index
while (++index < length) {
result[index] = `${index}`;
}
for (const key in value) {
if (
// If inherited by true Then traversal inheritance is allowed ( On the prototype ) The property name 
// Otherwise, only its own property name can be traversed 
(inherited || hasOwnProperty.call(value, key)) &&
// If value yes array or array-like
// And the current property name is length Or the current property is index
// Skip the current property name 
!(
skipIndexes &&
// Safari 9 In strict mode arguments.length It's enumerable 
(key === 'length' ||
// skip index
isIndex(key, length))
)
) {
result.push(key);
}
}
return result;
}
export default arrayLikeKeys;
 Copy code 

arrayLikeKeys Functions are difficult to understand by reading the source code , So we need to parse it line by line .

const isArr = Array.isArray(value);
const isArg = !isArr && isArguments(value);
const isBuff = !isArr && !isArg && isBuffer(value);
const isType = !isArr && !isArg && !isBuff && isTypedArray(value);
const skipIndexes = isArr || isArg || isBuff || isType;
 Copy code 

A series of or and not operations , To judge value Is it array/array-like, If so, you need to collect index to result in , Otherwise, it's not necessary .

const length = value.length;
const result = new Array(skipIndexes ? length : 0);
 Copy code 

If collection is required index Then instantiate one with value An array of equal length , Otherwise, instantiate a length of 0 Array of .

let index = skipIndexes ? -1 : length;
while (++index < length) {
result[index] = `${index}`;
}
 Copy code 

Empathy , If collection is required index, You need to index Initialize to -1, Traverse left to right , Otherwise, skip the collection index The process of ( Traverse ).

But you can see that it's used later for...in Traverse value Of key,index It should also be traversed , Why do you still use a while Loop to traverse index Well ?

This involves a more in-depth knowledge point :

const arr = new Array(100);
arr[0] = 0;
arr[50] = 50;
arr[99] = 99;
for (const index in arr) {
console.log(index);
}
// => 0
// => 50
// => 99
 Copy code 

When the array is sparse ,for...in It doesn't traverse all index.

for (const key in value) {
if (
(inherited || hasOwnProperty.call(value, key)) &&
!(skipIndexes && (key === 'length' || isIndex(key, length)))
) {
result.push(key);
}
}
 Copy code 

value Other properties on need to use for...in Traverse , because for...in It's also traversing value Properties on prototypes , So we need to make a layer of judgment on attributes .

inherited || hasOwnProperty.call(value, key);
 Copy code 

inherited by true Allow traversal of properties on the prototype , Otherwise, you can only traverse your own properties .

!(skipIndexes && (key === 'length' || isIndex(key, length)));
 Copy code 

When value by array/array-like when ,index It's been traversed , So here we're going to skip .

however Safari 9 In strict mode arguments.length It's enumerable , So it will be traversed to , Need to get rid of .

Finally, all the property names that meet the criteria will be push To result And in return .

arrayLikeKeys Function introduces isArgumentsisBufferisIndexisTypedArray function , So the implementation of these functions also needs to know .

import getTag from './.internal/getTag.js';
import isObjectLike from './isObjectLike.js';
/**
* testing value Is it arguments object
*
* @since 0.1.0
* @category Lang
* @param {*} value The values that need to be detected
* @returns {boolean}  If value by arguments Object returns true Otherwise return to false
* @example
*
* isArguments(function() { return arguments }())
* // => true
*
* isArguments([1, 2, 3])
* // => false
*/
function isArguments(value) {
return isObjectLike(value) && getTag(value) == '[object Arguments]';
}
export default isArguments;
 Copy code 

isArguments Function is introduced again isObjectLike and getTag function , So the implementation of these functions also needs to know .

/**
* testing value Is it object-like
* object-like Of value Not for null And typeof As the result of the "object"
*
* @since 4.0.0
* @category Lang
* @param {*} value The values that need to be detected
* @returns {boolean}  If value by object-like Then return to true Otherwise return to false
* @example
*
* isObjectLike({})
* // => true
*
* isObjectLike([1, 2, 3])
* // => true
*
* isObjectLike(Function)
* // => false
*
* isObjectLike(null)
* // => false
*/
function isObjectLike(value) {
// JavaScript an issue rooted in history 
// typeof null === "object"
// In the initial JavaScript in The value is based on 32 Bit for a memory unit 
// Each memory unit contains 1~3 The actual data content of bit type tags and values 
// The type is marked 000 The value of is object The actual data content is the reference of the object 
// null Indicates null value namely 32 All the seats are 0
return typeof value === 'object' && value !== null;
}
export default isObjectLike;
 Copy code 
/* from Object Of prototype Pick up toString Used to get type tags */
const toString = Object.prototype.toString;
/**
* obtain value Of toStringTag
*
* @private
* @param {*} value The values that need to be detected
* @returns {string}  return toStringTag
*/
function getTag(value) {
// Take advantage of JavaScript stay == The feature that automatically casts the type when the 
// It's filtered out undefined and null
if (value == null) {
return value === undefined ? '[object Undefined]' : '[object Null]';
}
return toString.call(value);
}
export default getTag;
 Copy code 

Whereas isBufferisIndexisTypedArray The function is more complex , Please look at the next breakdown .

版权声明
本文为[Red plume]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/05/20210504110147976j.html

  1. JS: event flow
  2. Front end performance optimization: rearrangement and redrawing
  3. JS - deep and shallow copy
  4. JavaScript异步编程3——Promise的链式使用
  5. JavaScript asynchronous programming 3 -- chain use of promise
  6. Vue.js组件的使用
  7. The use of vue.js component
  8. How to judge whether a linked list has links
  9. Element UI custom theme configuration
  10. Text image parallax effect HTML + CSS + JS
  11. Spring的nohttp宣言:消灭http://
  12. Vue3 intermediate guide - composition API
  13. Analysis of URL
  14. These 10 widgets that every developer must know
  15. Spring's nohttp Manifesto: eliminate http://
  16. Learn more about JS prototypes
  17. Refer to await to JS to write an await error handling
  18. A short article will directly let you understand what the event loop mechanism is
  19. Vue3 uses mitt for component communication
  20. Characteristics and thinking of ES6 symbol
  21. Two way linked list: I'm no longer one-way driving
  22. Vue event and form processing
  23. Reactive TraderCloud实时外汇开源交易平台
  24. Reactive tradercloud real time foreign exchange open source trading platform
  25. Node.js REST API的10个最佳实践
  26. Ten best practices of node.js rest API
  27. Fiddler advanced usage
  28. Process from Vue template to render
  29. Promise up (asynchronous or synchronous)
  30. Principle and implementation of promise
  31. Vs code plug in sharing - run code
  32. Vue practical notes (1) introduction of Ant Design
  33. Vue actual combat notes (2) introduction of element plus
  34. Introduction to webpack
  35. Webpack construction process
  36. Vue notes
  37. The experience and lessons of moving from ruby megalith architecture to go microservice
  38. Using leancloud to add artitalk module to hexo blog
  39. Implementation of chrome request filtering extension
  40. Detailed introduction of beer import declaration elements and label quarantine [import knowledge]
  41. Gallop workflow engine design series 01 process element design
  42. VUE移动端音乐APP学习【十六】:播放器歌词显示开发
  43. Vue Mobile Music App learning [16]: player lyrics display development
  44. jquery cookie
  45. jquery cookie
  46. 体面编码之JavaScript
  47. JavaScript for decent coding
  48. React17 系统精讲 结合TS打造旅游电商平台
  49. React17 system combined with TS to build tourism e-commerce platform
  50. 2021-05-04 hot news
  51. HttpSession对象与Cooike的关系 以及 Cookie对象构造函数问题
  52. gRPC-Web:替代REST的gRPC的Javascript库包
  53. The relationship between httpsession object and cooike and the construction of cookie object
  54. Grpc Web: a JavaScript library package to replace rest grpc
  55. Building reactive rest API with Java - kalpa Senanayake
  56. PDF转HTML工具——用springboot包装pdf2htmlEX命令行工具
  57. Pdf to HTML tool -- Wrapping pdf2htmlex command line tool with springboot
  58. PDF转HTML工具——用springboot包装pdf2htmlEX命令行工具
  59. Pdf to HTML tool -- Wrapping pdf2htmlex command line tool with springboot
  60. Vue.js比jQuery更容易学习