为什么在回调中传递的值返回undefined?

时间:2016-04-13 03:10:15

标签: javascript jquery

这里我试着在jquery中编写一个自定义的每个方法,因为在每个函数中我都会检查对象是否是类似数组,以及它是否像运行循环那样的数组并通过发送aruguments来调用回调函数在每个功能。在每个函数中我获得正确的值,但在回调中它们返回为未定义。

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)

2 个答案:

答案 0 :(得分:2)

问题是,要call()传递objidcall的第一个参数将作为this的值传递给obj回调和第二个参数将作为第一个参数的值传递,依此类推。因此,在您的情况下,this作为id的值传递,ob作为ik的值传递,因此this已经变为未定义没有价值传递给它。

一种解决方案是使用obj[i]来引用回调中的当前元素,另一种方法是将this作为cb.call(obj[i], obj[i], 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)
}

由于您将dom对象本身传递给回调,因此无需传递id

&#13;
&#13;
<!-- 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>
&#13;
{{1}}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

根据MDN,你以错误的方式调用Function.prototype.call()。当调用call()函数时,第一个参数是调用函数中this的值。调用函数的参数从call()函数中的第二个参数开始。

以下是MDN的一个例子,

var animals = [
  { species: 'Lion', name: 'King' },
  { species: 'Whale', name: 'Fail' }
];

for (var i = 0; i < animals.length; i++) {
  (function(i) {
    this.print = function() {
      console.log('#' + i + ' ' + this.species
                  + ': ' + this.name);
    }
    this.print();
  }).call(animals[i], i);
}

您未定义,因为您没有通过cb.call(obj,id)传递给您的第二个参数

因此,将您的参数作为第2和第3个参数传递给call()函数将解决您的问题。

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