这里我试着在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)
答案 0 :(得分:2)
问题是,要call()
传递obj
和id
,call
的第一个参数将作为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
<!-- 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;
答案 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)
}
}
}