One question a day, keep thinking

Today’s implementation is the forEach function, which iterates over arrays and objects, and a “niche” function that changes the reference to “this” within the function.

The problem

/ / object
forEach({a: 1.b: 2.c: 3}, function eachHandler(item, index, obj) {... },null);
/ / array
forEach([1.2.3].function eachHandler(item, index, obj) {... },null);
Copy the code

The specific implementation

function forEach(obj, fn, context) {
  // Null or undefined
  if (obj === null || typeof obj === 'undefined') {
    return;
  }
	// Other types become members of the new array
  if (typeofobj ! = ='object') {
    obj = [obj];
  }
	// Check whether it is an array
  if (Object.prototype.toString.call(obj) === '[object Array]') {
    var index = -1,
        length = obj.length;
    // Use while traversal
    while(++index < length) { fn.call(context, obj[index], index, obj); }}else {
    for (var key in obj) {
      // Borrow the hasOwnProperty on the object, excluding properties on the prototype chain
      if (Object.prototype.hasOwnProperty.call(obj, key)) { fn.call(context, obj[key], key, obj); }}}}Copy the code

Implementation approach

Parameters:

  1. obj(Array | Object) : need to traverse the value;
  2. fn(Function) : callback Function, parameter (The value currently traversed.Key or index value.A primitive array or object);
  3. context: the context object, which is the value bound to this in the callback function, defaults toundefined;

This method is mainly to implement the idea, mainly by judging whether it is an array, through the call method to execute the function fn called each time. If obj is declared, it is declared. If obj is declared, it is declared. If obj is declared, it is declared. Other non-object types (string, Boolean, number) are added to the new array. Next, we divide it into objects and arrays. The array is traversed by while. Finally, we bind this to fn’s call method. Object using for… In traversal, but this traversal will traverse properties on the stereotype chain, so use the hasOwnProperty method to determine whether the current property belongs to the current object rather than the stereotype chain, but in case the hasOwnPropery property is overwritten on the current object, So here we borrow the hasOwnProperty method from the Object prototype.

If you see something wrong or could be improved, feel free to comment. If you think it’s good or helpful, please like, comment, retweet and share. Thank you