开发者

Javascript local variable works like class variable in window

开发者 https://www.devze.com 2023-01-10 04:03 出处:网络
I find this behavior of the global window开发者_JS百科 object a little weird. var x = 10; function SomeClass(){

I find this behavior of the global window开发者_JS百科 object a little weird.

var x = 10;
function SomeClass(){
    var y = 15;
    console.log("Someclass:y - " + this.y); //prints undefined
}

console.log("window.x: " + window.x);   //prints 10

var obj = new SomeClass();
console.log("obj.y: " + obj.y); //prints - undefined

Both variables x and y are local (to window and to SomeClass respectively). Despite calling y from an object context, it only prints undefined - presumably because that is how local variables are supposed to behave. But window.x behaves differently by printing value of x. I understand that this is how you create global varibles but is this a special property of window that makes local variables behave like object variables?


According to the ECMAScript language specification:

If the variable statement occurs inside a FunctionDeclaration, the variables are defined with function-local scope in that function, [...]. Otherwise, they are defined with global scope (that is, they are created as members of the global object [...])

Essentially this means the var keyword has a slightly different meaning inside a function and in the global scope.

I think one way to look at it is that creating a variable in global scope is more like setting an instance variable on an object after it is created than like setting a local variable.

Compare setting a local variable in the constructor:

function SomeClass(){ 
    var y = 15; 
} 

var obj = new SomeClass(); 
console.log("obj.y: " + obj.y); //prints - undefined 

and setting a instance variable after the object is created:

function SomeClass(){ 
} 

var obj = new SomeClass(); 
obj.y = 15;
console.log("obj.y: " + obj.y); //prints - 15


in order to achieve what you are trying to with var y, it should be this.y = 15; That will allow you to reference it via this.y but also obj.y The reason it is printing undefined is simply because y is not assigned to be a member of SomeClass, just as a random variable within it.

http://www.javascriptkit.com/javatutors/object.shtml


you need to define y as a member of SomeClass. Otherwise it's just a local private variable within the closure of function SomeClass, but not a publicly accessible member of a SomeClass object, so:

function SomeClass(){
    this.y = 15;
    console.log("Someclass:y - " + this.y); //prints 15
}

Good question though about a variable assigned to the global space also being an attribute of window, not sure about that one. One would think you would need

this.x="something"

in order to access it through window.x


The key point to take away is that in your class example, y is private.

As the others have mentioned there are a few ways you can make it a public member variable, but the point I wanted to mention is that the fact that the following structure:

function SomeClass(){
  var y = 15;
}

...can be used to your advantage since it is private.

Typically I use a couple of different patterns for creating classes and objects this but one neat thing you can do is return an object literal from your function that has functions embedded in it that can reference y, while not exposing y to the outside world.

Pop this example into a page and try it out and see that you can read from and write to y using accessor methods:

<script type="text/javascript">
function SomeClass() {
  var y = 15;
  return {
    getY : function() { return y },
    setY : function(newY) { y = newY; }
  };
};

var obj = new SomeClass();

function showY() {
    alert("obj.getY: " + obj.getY()); // alerts current value of y.
}

function updateY() {    
    obj.setY(25);
    alert("updated.");
}

</script>
<input type="button" onclick="showY();return false;" value="showY"/>
<input type="button" onclick="updateY();return false" value="updateY"/>

Then click on "showY" first, then "updateY", then "showY" again to see the behavior.

This isn't the only pattern I personally use, but javascript is so flexible there's a lot of fun things you can do with it.

Hope I didn't blast you too much with that, and hope it helps a little bit with the concepts!

0

精彩评论

暂无评论...
验证码 换一张
取 消