-3

var Type = {};

for (var i = 0, type; type = ['String', 'Array', 'Number'][i++];) {
  (function(type) {
    Type['is' + type] = function(obj) {
      console.log(obj)
      return Object.prototype.toString.call(obj) === '[object ' + type + ']';
    }
  })(type);
}

console.log(Type.isArray([]))

console.log(Type.isString('str'))

Very confused why 'obj' is equal to 'type'

yunzen
  • 32,854
  • 11
  • 73
  • 106
ylmz_smz
  • 3
  • 2
  • "Very confused why 'obj' is equal to 'type'" — You never call the function which uses `obj` so … it isn't, at least not in the code you've shared with us. – Quentin Jan 22 '19 at 14:40
  • Welcome to SO! Please review this: [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) - You've done a great job at the Minimal and Complete parts, but since your code doesn't really do anything, the Verifiable part needs work. Please provide a properly written example. For instance, your `for` loop only has two arguments while you are attempting to increment your counter in the "test" rather than the incrementor. It is unclear what you are trying to achieve. – Randy Casburn Jan 22 '19 at 14:46
  • Thank you very much for your answer. For example, when I call Type.isArray([]), when the function executes to Type [is'+ type +'] = function(obj){}, I am confused why the value of obj will be ‘type’. – ylmz_smz Jan 22 '19 at 15:07

1 Answers1

0

See the comments in the code

var Type = {};

// This is like 
// types = ['String', 'Array', 'Number'];
// for (var i = 0; i < types.lenght; i++) {
//   var type = types[i];
//   // ...
// }
// type = undefined;
for (var i = 0, type; type = ['String', 'Array', 'Number'][i++];) {

  // This is like
  // var closure = function(type) {
  //   // ...
  // };
  // closure(type)
  (function(type) {

    // The global object 'Type' is getting a new element which is a function.
    // This element has a name which consists of the prefix 'is'
    // and the value of the varaible 'type'
    // ('String', 'Array', or 'Number')
    // So after the for loop Type will have functions 'isString', 'isArray' ,and 'isNumber'
    // 'obj' will store the parameter that the function is called with
    // for example: Type.isArray([1,2,3]) will store [1,2,3] with the variable obj 
    Type['is' + type] = function(obj) {
      // Since this is a function inside of a function,
      // the variable 'type' is known inside this (inner) function 
      // with the value it has at the time the outer was called
      // (@see JavaScript closures)
      console.log('type', type, 'obj', obj)
      // This is a little trick. The `toString()` method of arrays, strings, and numbers outputs the contents of these objects. The same method of an object returns '[object Object]'
      // Here we bend that `toString` method of the object 'class' to be called from within 
      // our Array, String, or Number and get what we need
      //
      // Why don't just use `typeof` operator? Because `typeof [] === 'object'`
      //
      // This will return true, if the String representation of 'obj'
      // fits type
      return Object.prototype.toString.call(obj) === '[object ' + type + ']';
    }
  })(type);
  
  // This was called three times
  // Type has now three new elements: 'isString', 'isArray', 'isNumber', all being functions
}

console.log(Type.isArray([]))

console.log(Type.isString('str'))

console.log(typeof [])

Addendum

You might have struggled with the syntax of object creation and access, as there are two ways to access values assigned to keys of objects

// They all overwrite the value of assigned to the key `myKey`
var key='Key';
myObj = {myKey: 'literal object initializer', unchanged: 'This value will remain unchanged in this example'};
console.log(myObj)

myObj.myKey = 'object access operator; dot notation';
console.log(myObj)

myObj['myKey'] = 'object access operator; brackets notation';
console.log(myObj)

myObj['my' + 'Key'] = 'object access operator; brackets notation with string concatenation';
console.log(myObj)

myObj['my' + key] = 'object access operator; brackets notation with string concatenation and variable interpolation';
console.log(myObj)

See the MDM documentation on Objects and Properties

yunzen
  • 32,854
  • 11
  • 73
  • 106