我是否正确理解了这段代码?

时间:2015-07-31 06:44:24

标签: javascript

我正在使用cordova s​​qlite插件。我的问题不要求您了解API。我没有任何问题。我对下面的代码及其工作原理的理解有点不确定。我试图更好地理解我编写的代码。

  1. 首先,这个变量" db"被定义为一个名为" openDatabase"的函数(对象);使用插件理解的参数并调用它。

  2. "分贝"这实际上是一个名为" openDatabase"的函数(对象)。有一个名为" transaction"的方法。

  3. 到目前为止我做得好吗?

    这里我有点困惑:现在等于openDatabase函数的db变量有一个名为transaction的方法,它有一个自调用函数作为参数,自调用函数有这个变量& #34; TX"作为参数? " tx"来自?它是" openDatabase"函数在被调用后返回?或者它不是从" openDatabase"它只是插件中的一个对象?假设变量作为我尚未在任何地方定义的参数,工作是否已经在我使用的插件,库或API中定义,这是否总是安全的?我的最后一个问题是,为什么使用自调用函数作为参数而不是定义为自调用函数的变量?有什么好处?谢谢。

    var db = openDatabase("DBTest", "1.0", "Sample Description", 200000);
    
    db.transaction(function(tx) {
        tx.executeSql("SELECT * FROM Table1Test", [], function(tx, result) {
        for (var i = 0, item = null; i < result.rows.length; i++) {
            item = result.rows.item(i);
            document.getElementById('results').innerHTML +=
                '<li><span> + item['text'] + '</span></li>';
        }
    });
    

4 个答案:

答案 0 :(得分:0)

以下是该代码中发生的事情,然后我会回答您的具体问题:

db被设置为openDatabase返回值。然后,代码调用db.transaction,传入回调函数。回调由db.transaction调用,它提供tx值,在回调中调用tx.executeSql,传入第二个回调函数。 executeSql调用带有结果的第二个回调,第二个回调中的代码循环遍历。

您的问题:

  

首先,这个变量&#34; db&#34;被定义为一个名为&#34; openDatabase&#34;的函数(对象);使用插件理解的参数并调用它。

没有。 openDatabase称为db被设置为其返回值。该返回值似乎是一个对象,但不是一个函数(虽然它可能是,没有证据表明它是,它可能不是)。

  

&#34;分贝&#34;这实际上是一个名为&#34; openDatabase&#34;的函数(对象)。有一个名为&#34; transaction&#34;。

的方法

是的,除了db可能不是一个函数(尽管它可能是),它只是一个对象。

  

db变量现在等同于openDatabase函数...

不是。

  

...有一个名为transaction的方法,它有一个自调用函数作为参数......

这不是自我调用。

  

...并且自调用函数具有此变量&#34; tx&#34;作为参数? &#34; tx&#34;来自?

因为回调函数不是自调用,所以tx参数的值来自调用回调的人。 transaction方法中的代码将在该代码中调用匿名回调。如果是,它将为该函数提供tx参数的值。同样,传入executeSql的回调也会调用txresult的值。

  

将变量假设为我在任何地方都没有定义的参数是否总是安全的......

可能不是。相反,继续你的JavaScript研究(你明确在学习过程中,这很棒)。您将学习语法,并能够分辨出什么是参数,什么是变量等等。以下是评论的一些信息:

var db = openDatabase("DBTest", "1.0", "Sample Description", 200000);
//  ^^---- variable

db.transaction(function(tx) {
// Argument ------------^^
    tx.executeSql("SELECT * FROM Table1Test", [], function(tx, result) {
// Arguments ----------------------------------------------^^--^^^^^^
        for (var i = 0, item = null; i < result.rows.length; i++) {
// Variables ----^------^^^^
            item = result.rows.item(i);
            document.getElementById('results').innerHTML +=
                '<li><span>' +
                item['text'] + '</span></li>';
        }
    });
});

这里的一些混乱似乎是回调,所以让我们看一个更简单的回调版本,以及我们可以看到它的两面。

假设有些东西为我们提供了一个函数countUp,我们可以给它一个开始和结束值,然后用以下每个值调用我们:

countUp(0, 5, function(value) {
    console.log(value);
});

假设我们使用它时,我们得到:

0
1
2
3
4

在上面的代码中,我们创建但从未调用我们传递给countUp的回调。调用回调的 countUp代码。这是countUp的样子:

function countUp(start, end, callback) {
//                           ^^^^^^^^---- the callback argument
    var i;
    for (i = start; i < end; ++i) {
//      vvvvvvvv------- calls our callback
        callback(i);
//               ^----- passing in this, which we get as `value`
    }
}

直播示例:

&#13;
&#13;
function countUp(start, end, callback) {
  var i;
  for (i = start; i < end; ++i) {
    callback(i);
  }
}

countUp(0, 5, function(value) {
  snippet.log(value);
});
&#13;
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

  

首先,这个变量&#34; db&#34;被定义为一个名为&#34; openDatabase&#34;的函数(对象);使用插件理解的参数并调用它。

没有。存储在openDatabase中的函数称为,并且返回值被分配给db

  

&#34;分贝&#34;这实际上是一个名为&#34; openDatabase&#34;的函数(对象)。有一个名为&#34; transaction&#34;。

的方法

分配给db的值是一个对象。

可能是一个函数,但代码中没有证据表明它是。

它有一个名为transaction的方法。

  

它有一个自调用函数作为参数

不,它没有。

foo( function () { } );
bar( function () { }() );

foo有一个函数作为参数。

bar将立即调用的函数表达式的返回值作为参数。

您不能将IIFE作为参数本身,因为IIFE会在将值传递给函数之前解析。

transaction有一个函数作为参数传递。

  

&#34; tx&#34;来自?

transaction函数(假设匿名函数不会先传递一些函数)将调用匿名函数。它会在它发生时传递参数。

  

将变量假设为我尚未在任何地方定义的参数是否始终是安全的,这些工作是否已在我使用的插件,库或API中定义?

  

我的最后一个问题是,为什么使用自调用函数作为参数而不是定义为自调用函数的变量?

如果你的意思是为什么使用函数表达式而不是存储在变量中的函数?那么它只保存创建变量的步骤,并将所有代码保存在一起。

答案 2 :(得分:0)

openDatabase是一个函数,它返回一个被赋值给db变量的对象。该对象有一个方法transaction,它将一个函数作为参数。当您调用事务方法时,它会设置一个事务,然后调用您传递的函数,并将新创建的事务作为其参数(示例中为tx)。该函数现在可以使用事务来查询数据库。返回时,transaction方法将执行任何必要的清理,然后返回到顶层代码。

答案 3 :(得分:0)

这个评论太长了,但没有直接回答这个问题。但是,理解这个概念有望让您自己回答所有问题。因此,我将此作为答案发布。

主要概念:函数只是数字,字符串等对象。

你可能已经看到过这样的代码:

var x = function (a) {...}

这不是声明函数的特殊语法。它只是可能因为函数是javascript中的第一类。一流是指编程语言中可被视为数据的东西。在大多数语言中,数字和数组是一流的“东西”(我现在避免使用“对象”这个词,因为它可能在某些语言中具有特定的含义,包括javascript)。在很多语言中,字符串也是一流的东西。在一些语言中,甚至函数都是一流的东西。

Javascript是一种语言,其中函数是一流的:它们可以被视为数据

function x () {};

// you can assign them to variables:
var y = x;
y(); // call the function

// you can put them in arrays:
var a = [x,y];
a[0](); // call the function

// you can pass them as argument:
funtion b (foo) {
    foo(); // call the function passed to b()
}
b(x); // this will cause b() to call x()

所以当你看到这个:

db.transaction(function(tx) {/*...*/});

它基本上是这样做的:

function my_function (tx) {/*...*/}

db.transaction(my_function);

因此,您可以猜测db.transaction()看起来像这样:

db.transaction = function (another_function) {
    /* complicated processing ... */

    another_function(result); // pass result variable to the function
                              // the user gave us.
}

所以当你打电话时:

db.transaction(function(tx) {/*...*/});

函数db.transaction()将调用您的函数并向其传递一个参数(您已将其定义为tx)。

tx视为db.transaction() return 值。