javascript closure

JavaScript Closures for Dummies

Submitted by Morris on Tue, 2006-02-21 10:19. Community-edited since.

Closures Are Not Magic

This page explains closures so that a programmer can understand them — using working JavaScript code. It is not for gurus or functional programmers.

Closures are not hard to understand once the core concept is grokked. However, they are impossible to understand by reading any academic papers or academically oriented information about them!

This article is intended for programmers with some programming experience in a mainstream language, and who can read the following JavaScript function:

function sayHello(name) {
    var text = 'Hello ' + name;
    var say = function() { console.log(text); }
    say();
}

An Example of a Closure

Two one sentence summaries:

  • a closure is the local variables for a function — kept alive after the function has returned, or
  • a closure is a stack-frame which is not deallocated when the function returns (as if a ‘stack-frame’ were malloc’ed instead of being on the stack!).

The following code returns a reference to a function:

function sayHello2(name) {
    var text = 'Hello ' + name; // Local variable
    var say = function() { console.log(text); }
    return say;
}
var say2 = sayHello2('Bob');
say2(); // logs "Hello Bob"

Most JavaScript programmers will understand how a reference to a function is returned to a variable (say2) in the above code. If you don’t, then you need to before you can learn closures. A C programmer would think of the function as returning a pointer to a function, and that the variables sayand say2 were each a pointer to a function.

There is a critical difference between a C pointer to a function and a JavaScript reference to a function. In JavaScript, you can think of a function reference variable as having both a pointer to a function as well as a hidden pointer to a closure.

The above code has a closure because the anonymous function function() { console.log(text); } is declared inside another function, sayHello2() in this example. In JavaScript, if you use the function keyword inside another function, you are creating a closure.

In C and most other common languages, after a function returns, all the local variables are no longer accessible because the stack-frame is destroyed.

In JavaScript, if you declare a function within another function, then the local variables can remain accessible after returning from the function you called. This is demonstrated above, because we call the function say2() after we have returned from sayHello2(). Notice that the code that we call references the variable text, which was a local variable of the function sayHello2().

function() { console.log(text); } // Output of say2.toString();

Looking at the output of say2.toString(), we can see that the code refers to the variable text. The anonymous function can reference text which holds the value 'Hello Bob' because the local variables of sayHello2() are kept in a closure.

The magic is that in JavaScript a function reference also has a secret reference to the closure it was created in — similar to how delegates are a method pointer plus a secret reference to an object.

More examples

For some reason, closures seem really hard to understand when you read about them, but when you see some examples you can click to how they work (it took me a while). I recommend working through the examples carefully until you understand how they work. If you start using closures without fully understanding how they work, you would soon create some very weird bugs!

Example 3

This example shows that the local variables are not copied — they are kept by reference. It is kind of like keeping a stack-frame in memory when the outer function exits!

function say667() {
    // Local variable that ends up within closure
    var num = 666;
    var say = function() { console.log(num); }
    num++;
    return say;
}
var sayNumber = say667();
sayNumber(); // logs 667

Example 4

All three global functions have a common reference to the same closure because they are all declared within a single call to setupSomeGlobals().

var gLogNumber, gIncreaseNumber, gSetNumber;
function setupSomeGlobals() {
    // Local variable that ends up within closure
    var num = 666;
    // Store some references to functions as global variables
    gLogNumber = function() { console.log(num); }
    gIncreaseNumber = function() { num++; }
    gSetNumber = function(x) { num = x; }
}

setupSomeGlobals();
gIncreaseNumber();
gLogNumber(); // 667
gSetNumber(5);
gLogNumber(); // 5

var oldLog = gLogNumber;

setupSomeGlobals();
gLogNumber(); // 666

oldLog() // 5

The three functions have shared access to the same closure — the local variables of setupSomeGlobals() when the three functions were defined.

Note that in the above example, if you call setupSomeGlobals() again, then a new closure (stack-frame!) is created. The old gAlertNumber, gIncreaseNumber, gSetNumber variables are overwritten with new functions that have the new closure. (In JavaScript, whenever you declare a function inside another function, the inside function(s) is/are recreated again each time the outside function is called.)

Example 5

This one is a real gotcha for many people, so you need to understand it. Be very careful if you are defining a function within a loop: the local variables from the closure do not act as you might first think.

function buildList(list) {
    var result = [];
    for (var i = 0; i < list.length; i++) {
        var item = 'item' + i;
        result.push( function() {console.log(item + ' ' + list[i])} );
    }
    return result;
}

function testList() {
    var fnlist = buildList([1,2,3]);
    // Using j only to help prevent confusion -- could use i.
    for (var j = 0; j < fnlist.length; j++) {
        fnlist[j]();
    }
}

The line result.push( function() {console.log(item + ' ' + list[i])} adds a reference to an anonymous function three times to the result array. If you are not so familiar with anonymous functions think of it like:

pointer = function() {console.log(item + ' ' + list[i])};
result.push(pointer);

Note that when you run the example, "item2 undefined" is alerted three times! This is because just like previous examples, there is only one closure for the local variables for buildList. When the anonymous functions are called on the line fnlist[j](); they all use the same single closure, and they use the current value for i and item within that one closure (where i has a value of 3because the loop had completed, and item has a value of 'item2'). Note we are indexing from 0 hence item has a value of item2. And the i++ will increment i to the value 3.

Example 6

This example shows that the closure contains any local variables that were declared inside the outer function before it exited. Note that the variable alice is actually declared after the anonymous function. The anonymous function is declared first; and when that function is called it can access the alice variable because alice is in the same scope (JavaScript does variable hoisting). Also sayAlice()() just directly calls the function reference returned from sayAlice() — it is exactly the same as what was done previously, but without the temporary variable.

function sayAlice() {
    var say = function() { console.log(alice); }
    // Local variable that ends up within closure
    var alice = 'Hello Alice';
    return say;
}
sayAlice()();

Tricky: note also that the say variable is also inside the closure, and could be accessed by any other function that might be declared within sayAlice(), or it could be accessed recursively within the inside function.

Example 7

This final example shows that each call creates a separate closure for the local variables. There is nota single closure per function declaration. There is a closure for each call to a function.

function newClosure(someNum, someRef) {
    // Local variables that end up within closure
    var num = someNum;
    var anArray = [1,2,3];
    var ref = someRef;
    return function(x) {
        num += x;
        anArray.push(num);
        console.log('num: ' + num +
            '\nanArray ' + anArray.toString() +
            '\nref.someVar ' + ref.someVar);
      }
}
obj = {someVar: 4};
fn1 = newClosure(4, obj);
fn2 = newClosure(5, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;

Summary

If everything seems completely unclear then the best thing to do is to play with the examples. Reading an explanation is much harder than understanding examples. My explanations of closures and stack-frames, etc. are not technically correct — they are gross simplifications intended to help understanding. Once the basic idea is grokked, you can pick up the details later.

Final points:

  • Whenever you use function inside another function, a closure is used.
  • Whenever you use eval() inside a function, a closure is used. The text you eval can reference local variables of the function, and within eval you can even create new local variables by using eval('var foo = …')
  • When you use new Function(…) (the Function constructor) inside a function, it does not create a closure. (The new function cannot reference the local variables of the outer function.)
  • A closure in JavaScript is like keeping a copy of all the local variables, just as they were when a function exited.
  • It is probably best to think that a closure is always created just on entry to a function, and the local variables are added to that closure.
  • A new set of local variables is kept every time a function with a closure is called (given that the function contains a function declaration inside it, and a reference to that inside function is either returned or an external reference is kept for it in some way).
  • Two functions might look like they have the same source text, but have completely different behaviour because of their ‘hidden’ closure. I don’t think JavaScript code can actually find out if a function reference has a closure or not.
  • If you are trying to do any dynamic source code modifications (for example: myFunction = Function(myFunction.toString().replace(/Hello/,'Hola'));), it won’t work if myFunction is a closure (of course, you would never even think of doing source code string substitution at runtime, but…).
  • It is possible to get function declarations within function declarations within functions — and you can get closures at more than one level.
  • I think normally a closure is the term for both the function along with the variables that are captured. Note that I do not use that definition in this article!
  • I suspect that closures in JavaScript differ from those normally found in functional languages.

Links

Thanks

If you have just learned closures (here or elsewhere!), then I am interested in any feedback from you about any changes you might suggest that could make this article clearer. Send an email to morrisjohns.com (morris_closure @). Please note that I am not a guru on JavaScript — nor on closures.

Advertisements

Jual Video tutorial membuat Social network dengan Codeigniter studi kasus twitter

 

membuat jejaring sosial fitur follower dan follo wingdengan codeigniter

Saya merilis Video tutorial membuat Social network dengan Codeigniter harga Rp. 120.000,- bisa dipesan di Bukalapak dan Tokopedia.

Tutorial ini membahas tentang pembuatan fitur follower dan following, tombol follow dan unfollow, yang menarik di turorial ini adalah pembahasan  perancangan relationship table, bagaimana cara unik untuk mendesain database dari NOL BESAR sampai teknik Peng KODING an aplikasi dengan PHP Codeigniter Framework,

Link Bukalapak: https://www.bukalapak.com/p/buku/komputer-487/194ldu-jual-buku-video-tutorial-membuat-fitur-social-network-dengan-php-codeigniter

Link Tokopedia: https://www.tokopedia.com/slametnurhadi/video-tutorial-membuat-fitur-social-network-dengan-php-codeigniter

 

 

berisi Video :

  1. Memulai Proyek: membuat basis data dan table users
  2. Membuat Tabel users
  3. Membuat User  Register
  4. Membuat User Home untuk dashboard
  5. Membuat User login
  6. Membuar User detail
  7. Membuat User Logout
  8. Membuat Daftar User
  9. Teori dan konsep Relasi tabel
  10. Membuat tabel Follows dan Membuat Model follows
  11. Perancangan Logika Follow.
  12. perancangan logika Unfollow.
  13. Authentikasi User.
  14. Cek Authentikasi User.
  15. membuat tombol follow
  16. Menghilangkan Tombol follow pad Id  Login Sendiri
  17. Membuat Tombol follow dan Unfollow
  18. Proteksi follow dengan Session
  19. Halaman user follower
  20. halaman user following

 

proyek social network

Halaman user All

video tutorial codeigniter 5

halaman user Follower

 

video tutorial codeigniter 6

 

 

 

Halaman User Following

video tutorial codeigniter 7

Tampilan debgab Css Bootstrap 3:
user  all

preview 1

 
User detailpreview 2

 

User Home dashboard

preview 3

 

user login

preview 4

 

 

 

 

follow1

ini adalah contoh web saya pernah saya implementasikan sebuah fitur followind dan follower.

unfllow2

Pre Order dibuka untuk mendapatkan harga Rp. 100.000 melalui kontak facebook saya atau watsap 089636283068,  dikirim dari jakarta

Hormat saya,

Slamet Nurhadi

 

Multiple Google geo charts on One Page

multiple geo

Fixing Multiple google geo charts on One page, this tutorial is [solved] your problem.

official https://developers.google.com/chart/interactive/docs/gallery/geomap#overview

A geomap is a map of a country, continent, or region map, with colors and values assigned to specific regions. Values are displayed as a color scale, and you can specify optional hovertext for regions. The map is rendered in the browser using an embedded Flash player. Note that the map is not scrollable or draggable, but can be configured to allow zooming.
tutorial geo chart php mysqli xml

Tutorial  available on Youtube

Data Format

Two address formats are supported, each of which supports a different number of columns, and different data types for each column. All addresses in the table must use one or the other; you cannot mix types.

  • Format 1: Latitude/Longitude locations. This format works only when the dataMode option is ‘markers’. If this format is used, you do not need to include the Google Map Javascript. The location is entered in two columns, plus two optional columns:
    1. [Number, Required] A latitude. Positive numbers are north, negative numbers are south.
    2. [Number, Required] A longitude. Positive numbers are east, negative numbers are west.
    3. [Number, Optional] A numeric value displayed when the user hovers over this region. If column 4 is used, this column is required.
    4. [String, Optional] Additional string text displayed when the user hovers over this region.
  • Format 2: Address, country name, region name locations, or US metropolitan area codes. This format works with the dataMode option set to either ‘markers’ or ‘regions’. The location is entered in one column, plus two optional columns:
    1. [String, Required] A map location. The following formats are accepted:
      • A specific address (for example, “1600 Pennsylvania Ave”).
      • A country name as a string (for example, “England”), or an uppercase ISO-3166 code or its English text equivalent (for example, “GB” or “United Kingdom”).
      • An uppercase ISO-3166-2 region code name or its English text equivalent (for example, “US-NJ” or “New Jersey”). Note: Regions can only be specified when the dataMode option is set to ‘regions’.
      • A metropolitan area code. These are three-digit metro codes used to designate various regions; US codes only supported. Note that these are not the same as telephone area codes.
    2. [Number, Optional] A numeric value displayed when the user hovers over this region. If column 3 is used, this column is required.
    3. [String, Optional] Additional string text displayed when the user hovers over this region.

Tutorial  available on Youtube

 

Fixing Google Geo chart PHP + MYSQLi or XML parser complete tutorials

Fixing Google Geo chart PHP + MYSQLi or XML parser complete tutorials

 

Please Subscribe my Chanel on Youtube:

YouTube-Subscribe

google geo chart

Mysqltable is bellow:

google chart mysql

 

<?php $con = mysqli_connect('localhost','root','','test') or Die(); ?>
<html>
  <head>
   <script type="text/javascript" src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
      google.load("visualization", "1", {packages:["geochart"]});
      google.setOnLoadCallback(drawRegionsMap);

      function drawRegionsMap() {

        var data = google.visualization.arrayToDataTable([

          ['Country', 'Visits'],
           <?php $query = "SELECT count(ip) AS count, country FROM visitors GROUP BY country"; $exec = mysqli_query($con,$query); while($row = mysqli_fetch_array($exec)){ echo "['".$row['country']."',".$row['count']."],"; } ?>
        ]);

        var options = {
        	
        };

        var chart = new google.visualization.GeoChart(document.getElementById('geochartsatu'));

        chart.draw(data, options);
      }
    </script>
  
    

   
  </head>
  <body>
 



<h3>Geo Chart</h3>






<div id="geochartsatu" style="width: 900px; height: 500px;"></div>



  
   
         

  </body>
</html>

Comparison JSON and XML parsing with PHP it’s easy

unduhan

Comparison JSON and XML parsing with PHP it’s easy.

PHP SimpleXML Introduction

SimpleXML is an extension that allows us to easily manipulate and get XML data.

Installation

As of PHP 5, the SimpleXML functions are part of the PHP core. No installation is required to use these functions.

SimpleXML provides an easy way of getting an element’s name, attributes and textual content if you know the XML document’s structure or layout.

download

SimpleXML turns an XML document into a data structure you can iterate through like a collection of arrays and objects.

<?php
  $url = "http://data.bmkg.go.id/cuaca_indo_1.xml";
  $sUrl = file_get_contents($url, False);
  $xml = simplexml_load_string($sUrl);


for ($i=0; $i<sizeof($xml->Isi->Row); $i++) { 
	 $row = $xml->Isi->Row[$i];
?>

<a href="detailcuaca.php?detail=<?php echo $row->Kota; ?>"><?php echo $row->Kota; ?></a>
<?php echo "

Data Cuaca : ".$row->Cuaca." 

"; ?>
	

	   
<?php }?>

Google chart 2016 PHP + MYSQLi Connection

Google chart 2016 PHP + MYSQLi Connection theme case is Populer startup in Indonesia (data is Fiktif)

googlechart_php+myqliconnection

 

googlechart


<?php //open connection to mysql db $connection = mysqli_connect("localhost","root","","test") or die("Error " . mysqli_error($connection)); //fetch table rows from mysql db $sql = "select * from populer_startup"; $result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection)); //create an array $rows = array(); //flag is not needed $flag = true; $table = array(); $table['cols'] = array( // Labels for your chart, these represent the column titles // Note that one column is in "string" format and another one is in "number" format as pie chart only required "numbers" for calculating percentage and string will be used for column title array('label' => 'Startup', 'type' => 'string'),
    array('label' => 'Users', 'type' => 'number')
 
);
	

	$rows = array();
    while($r =mysqli_fetch_assoc($result))
    {
    $temp = array();
    // the following line will be used to slice the Pie chart
    $temp[] = array('v' => (string) $r['name']); 
 
    // Values of each slice
    $temp[] = array('v' => (int) $r['custommer']);
    $rows[] = array('c' => $temp);
    }
	
  $table['rows'] = $rows;
   $jsonTable = json_encode($table);

?>



<html>
  <head>
    <!--Load the Ajax API-->
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script type="text/javascript">
 
    // Load the Visualization API and the piechart package.
    google.load('visualization', '1', {'packages':['corechart']});
 
    // Set a callback to run when the Google Visualization API is loaded.
    google.setOnLoadCallback(drawChart);
 
    function drawChart() {
 
      // Create our data table out of JSON data loaded from server.
      var data = new google.visualization.DataTable(<?=$jsonTable?>);
      var options = {
           title: 'Populer startup in Indonesia. ',
          is3D: 'true',
          width: 800,
          height: 600
        };
      // Instantiate and draw our chart, passing in some options.
      // Do not forget to check your div ID
      var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }
    </script>
  </head>
 
  <body>
    <!--this is the div that will hold the pie chart-->

<div id="chart_div"></div>

  </body>
</html>

Google chart + php + mysql lanjutan 2

Tutorial google chart untuk php dan mysql
donatgchart_sql


<?php /* Script : PHP-JSON-MySQLi-GoogleChart Author : Enam Hossain version : 1.0 */ /* -------------------------------------------------------------------- Usage: -------------------------------------------------------------------- Requirements: PHP, Apache and MySQL Installation: --- Create a database by using phpMyAdmin and name it "chart" --- Create a table by using phpMyAdmin and name it "googlechart" and make sure table has only two columns as I have used two columns. However, you can use more than 2 columns if you like but you have to change the code a little bit for that --- Specify column names as follows: "weekly_task" and "percentage" --- Insert some data into the table --- For the percentage column only use a number --------------------------------- example data: Table (googlechart) --------------------------------- weekly_task percentage ----------- ---------- Sleep 30 Watching Movie 10 job 40 Exercise 20 */ /* Establish the database connection */ // $mysqli = new mysqli_connect('127.0.0.1:3306', 'root', 'root', 'test'); /* if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } */ $mysqli =mysqli_connect('localhost', 'root', '', 'rumahsakit'); if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: ".mysqli_connect_error(); } /* select all the weekly tasks from the table googlechart */ $result = $mysqli->query(' SELECT tgldaftar, COUNT( * ) AS count, SUM( 100 ) / total AS percentage
FROM t_pasien CROSS JOIN (
SELECT COUNT( * ) AS total
FROM t_pasien ) x GROUP BY MONTH( tgldaftar )
 ');

  /*
      ---------------------------
      example data: Table (googlechart)
      --------------------------
      Weekly_Task     percentage
      Sleep           30
      Watching Movie  10
      job             40
      Exercise        20
  */

  $rows = array();
  $table = array();
  $table['cols'] = array(

    // Labels for your chart, these represent the column titles.
    /*
        note that one column is in "string" format and another one is in "number" format
        as pie chart only required "numbers" for calculating percentage
        and string will be used for Slice title
    */
    array('label' => 'tgldaftar', 'type' => 'string'),
    array('label' => 'percentage', 'type' => 'number')

);
    /* Extract the information from $result */
    foreach($result as $r) {

      $temp = array();

      // The following line will be used to slice the Pie chart

      $temp[] = array('v' => (string) $r['tgldaftar']); 

      // Values of the each slice

      $temp[] = array('v' => (int) $r['percentage']);
      $rows[] = array('c' => $temp);
    }

$table['rows'] = $rows;

// convert data into JSON format
$jsonTable = json_encode($table);
//echo $jsonTable;

?>

    <!--Load the Ajax API-->
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script type="text/javascript">

    // Load the Visualization API and the piechart package.
    google.load('visualization', '1', {'packages':['corechart']});

    // Set a callback to run when the Google Visualization API is loaded.
    google.setOnLoadCallback(drawChart);

    function drawChart() {

      // Create our data table out of JSON data loaded from server.
      var data = new google.visualization.DataTable(<?=$jsonTable?>);
      var options = {
           title: 'jumlah Pasien berdasarkan Periode Bulan',
        //  is3D: 'true',
          width: 550,
          height: 400,
          pieHole: 0.4,
        };
      // Instantiate and draw our chart, passing in some options.
      // Do not forget to check your div ID
      var chart = new google.visualization.PieChart(document.getElementById('donutchart'));
      chart.draw(data, options);
    }
    </script>

    <!--this is the div that will hold the pie chart-->

<div id="donutchart"></div>