why do the values ​​passed in a recall be returned indefinitely?

advertisements

Here im trying to write a custom each method as in jquery, for that in each function im checking whether the object is array-like or not and if it is array like im running a loop and calling a callback function by sending aruguments in each function. in each function im getting correct values but in call back they are returning as undefined.

var obj = document.getElementsByTagName('input');

var isArrayLike = function(obj){
    if(typeof obj.length === "number"){
        if(obj.length===0){
            return true;
        }
        else if(obj.length>=0){
            return (obj.length)-1 in obj;
        }
    }
    return false;
}

function cb(ob,ik){
//here value of ob is returning as 2 and id as undefined
    console.log(ob)
    console.log(ik)
    if(document.getElementById(ik).checked){
         console.log(ik)
    }
}

function each (obj,cb) {
    if(isArrayLike(obj)){
        for(var i=0;i<obj.length;i++){
            var id = obj[i].getAttribute('id');
            cb.call(obj,id)
        }
    }
}

each(obj,cb)

The problem is, to call() you are passing obj and id, the first argument to call will be passed as the value of this in the callback and second argument will be passed as the value of first parameter and so on. So in your case obj is passed as the value of this and the id is passed as the value of ob, so ik has become undefined since there is no value passed to it.

One solution is to use this to refer to the current element in the callback, another is to pass the obj[i] as the this value and as the first parameter.

cb.call(obj[i], obj[i], id)


Since you are passing the dom object itself to the callback, there is no need to pass the id

var obj = document.getElementsByTagName('input');

var isArrayLike = function(obj) {
  if (typeof obj.length === "number") {
    if (obj.length === 0) {
      return true;
    } else if (obj.length >= 0) {
      return (obj.length) - 1 in obj;
    }
  }
  return false;
}

function cb(ob) {
  //here value of ob is returning as 2 and id as undefined
  console.log(ob, this)
  if (ob.checked) {
    snippet.log(ob.id)
  }
}

function each(obj, cb) {
  if (isArrayLike(obj)) {
    for (var i = 0; i < obj.length; i++) {
      cb.call(obj[i], obj[i])
    }
  }
}

function testit() {
  each(obj, cb)
}
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<input type="checkbox" id="1" />
<input type="checkbox" id="2" />

<button onclick="testit()">Test</button>