2016-04-13 22 views
2

ここではjqueryのようにそれぞれのメソッドを書くつもりですが、各関数imはオブジェクトが配列のようなものかどうかをチェックし、imはループを実行し、arugumentsを送ることでコールバック関数を呼び出すような配列各機能それぞれの関数で正しい値を取得していますが、コールバックでは未定義として返ります。なぜコールバックで渡された値が未定義を返すのですか?

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

構文はhttps://developer.mozilla.org/en-US/に 'fun.call(thisArg [、引数1 [、ARG2 [、...]]])' –

+0

外観ですdocs/Web/JavaScript/Reference/Global_Objects/Function/call –

答えて

2

問題は、あなたがobjidを渡しているcall()callへの最初の引数は、コールバックでthisの値として渡されますし、二番目の引数として渡されます、です最初のパラメータの値などです。したがって、objthisの値として渡され、idobの値として渡されるため、値が渡されないのでikは未定義になります。

解決策の1つは、コールバックの現在の要素を参照するのにthisを使用し、値として、最初のパラメータとしてobj[i]を渡すことです。

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

あなたはコールバックにDOMオブジェクト自体を渡しているので、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

おかげで、コンテキストと引数は混同されました。この場合は両方とも同じですので、コンテキストと2番目の引数としてobjを2回渡してください。 – SameerShaik

0

MDNによると、あなたはFunction.prototype.call()を呼び出しています間違った方法で。call()ファンクションの最初のパラメータを呼び出すと、という値になります0を呼び出します。呼び出し元関数のパラメーターは、call()関数の2番目のパラメーターから開始します。ここで

はあなたに2つ目のパラメータを渡しませんでしたので、あなたは未定義だ、

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); 
} 

MDNの例であるので、call()に2番目と3番目のパラメータとして、あなたのパラメータを渡すcb.call(obj,id)

で機能関数があなたの問題を解決します。通話機能のための

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) 
    } 
} 
} 
関連する問題