2016-04-13 3 views
2

Hier versuche ich eine benutzerdefinierte Methode wie in jquery zu schreiben, dafür in jeder Funktion zu überprüfen, ob das Objekt array-artig ist oder nicht und ob es Array wie im Ausführen einer Schleife und Aufruf einer Callback-Funktion durch Senden von Aruguments in ist jede Funktion. In jeder Funktion werden die richtigen Werte erhalten, aber im Callback werden sie als undefiniert zurückgegeben.warum die in einem Callback übergebenen Werte undefined zurückgeben?

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

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

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

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

 
each(obj,cb)

+0

Syntax für die Anruffunktion ist 'fun.call (thisArg [, arg1 [, arg2 [, ...]]])' –

+0

Blick in https://developer.mozilla.org/en-US/ docs/Web/JavaScript/Referenz/Global_Objects/Function/call –

Antwort

2

Das Problem ist, zu call() Sie vorbei obj und id, das erste Argument call wird als der Wert von this in der Callback und dem zweiten Argument übergeben wird, als die übergeben werden Wert des ersten Parameters und so weiter. Also in Ihrem Fall wird obj als Wert von this übergeben und der id wird als Wert von ob übergeben, so dass undefined geworden ist, da kein Wert an es übergeben wird.

Eine Lösung this zu verwenden ist, auf das aktuelle Element in der Rückruf zu beziehen, die eine andere ist als die obj[i]this Wert und als ersten Parameter zu übergeben.

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

Da Sie das DOM-Objekt selbst an die Callback sind vorbei, gibt es keine Notwendigkeit, die 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>

+0

Danke, ich war verwirrt mit dem Kontext und Argument, da beide in diesem Fall gleich sind, also hätte ich obj für 2 mal als Kontext und als zweites Argument übergeben . – SameerShaik

0

Nach MDN Sie Function.prototype.call() fordern passieren falsch.Wenn Sie den ersten Parameter der Funktion call() aufrufen, ist der Wert this in der aufrufenden Funktion. Die Parameter für die aufrufende Funktion beginnen mit dem zweiten Parameter in der Funktion call(). Hier

ist ein Beispiel von 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); 
} 

Sie undefined bekam, weil Sie nicht einen zweiten Parameter übergeben haben Sie funktionieren mit cb.call(obj,id)

So Ihre Parameter als 2. vorbei und 3. Parameter call() Funktion wird dein Problem lösen.

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) 
    } 
} 
} 
Verwandte Themen