Javascript factory template scope

I follow the tutorial showing a factory template for creating objects in javascript. The following code puzzled me why it works.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>6-2.htm</title>
</head>
<body>
<script type="text/javascript">
function createAddress(street, city, state, zip) {
  var obj = new Object();
  obj.street = street;
  obj.city = city;
  obj.state = state;
  obj.zip = zip;
  obj.showLabel = function() {
    //alert(this.street + "\n" + this.city + ", " + this.state + " " + this.zip);
    //var obj;
    alert(obj.street + "\n" + obj.city + ", " + obj.state + " " + obj.zip);
  };
  return obj;
};

var JohnAddr = createAddress("12 A St.", "Johnson City", "TN", 37614);
var JoeAddr = createAddress("10061 Bristol Park", "Pensacola", "FL", 32503);

JohnAddr.showLabel();
JoeAddr.showLabel();
</script>
</body>
</html>

( this showLabel). , obj . obj -, , obj, ? 2 , , , obj . ? , , , , js, , .

+3
4

. , , , , , . , .

javascript / , Java C. , , .

, . - 'private' , , , . , , , .

, stackoverflow, javascript, , , :

JavaScript?

, JavaScript

Google " javascript", .


.

, this ( * cough *, , this , * cough *;-):

Javascript . , - . this , . , , , , . , this, , this.

javascript :

function foo () {
    alert(this.bar);
}

var bar = "hello";
var obj = {
    foo : foo,
    bar : "hi"
};
var second_obj = {
    bar : "bye"
};

foo(); // says hello, 'this' refers to the global object and this.bar
       // refers to the global variable bar.

obj.foo(); // says hi, 'this' refers to the first thing before the last dot
           // ie, the object foo belongs to

// now this is where it gets weird, an object can borrow/steal methods of
// another object and have its 'this' re-bound to it

obj.foo.call(second_obj); // says bye because call and apply allows 'this'
                          // to be re-bound to a foreign object. In this case
                          // this refers to second_obj

this , , , , -, , .

+6

obj showLabel, obj . , . JavaScript .

, factory.

:

var Address = function(street, city, state, zip){
    this.street = street;
    this.city = city;
    this.state = state;
    this.zip= zip;
};

Address.prototype.showLabel = function(){
    alert(this.street + "\n" + this.city + ", " + this.state + " " + this.zip);
}

, :

// create new address
var address = new Address('1', '2', '3', '4');
address.showLabel(); // alert

, . , this , window.

// create new address
var address = Address('1', '2', '3', '4'); // address == undefined
window.showLabel(); // address was added to window

, .

+2
function Address(street, city, state, zip) {

  this.street = street;
  this.city = city;
  this.state = state;
  this.zip = zip;
  this.showLabel = function() {
    //alert(this.street + "\n" + this.city + ", " + this.state + " " + this.zip);
    //var obj;
    alert(this.street + "\n" + this.city + ", " + this.state + " " + this.zip);
  };
};

var JohnAddr = new Address(...);
JohnAddr.showLabel();
+1

This is part of the weirdness of js, showLabel is a closure and has access to obj since it was in the scope when it was created - a new closure is created every time createAddress is called.

To use 'this' as you expect, you will need to use the new operator like this:

var foo = new createAddress (...

And assign member variables to 'this'.

In this case, when new is not used, 'this' is a global object.

0
source

Source: https://habr.com/ru/post/1779625/


All Articles