4

After invoking my function, I was startled that my function didn't throw up an error due having a variable & using a variable not define in the function's scope.

My question: Why doesn't my function throw an undefined,error, or the like? Shouldn't it throw up an error because "length" isn't in my function's parameter? I am aware that if I switch "length" to "height" it will work.

If someone could explain how javascript interprets this function in a step-by-step manner that would help me. Here is my code:

function areaRectangle(width, height) {
   aRectangle = width * length;
   console.log("The area of the rectangle is: " + aRectangle);
}
areaRectangle(10, 7); # The area of the rectangle is: 0
Clifford Fajardo
  • 1,357
  • 1
  • 17
  • 28
  • 2
    From the Mozilla docs: Assigning a value to an undeclared variable implicitly creates it as a global variable (it becomes a property of the global object) when the assignment is executed. – Joel Gregory Dec 29 '14 at 04:12

7 Answers7

6

Because instead of an argument or variable it uses window.length property which happens to be 0.

a sad dude
  • 2,775
  • 17
  • 20
  • So, the word "length" that I used is referring to Window.length? Don't you declare a property of a window by putting a dot in front of length? (.length) – Clifford Fajardo Dec 29 '14 at 04:35
5

This depends on which environment you execute this function in.

If you executed this in the browser, it seems like there is a length property in the global context which evaluates to a numeric value. When you execute your function in the console and it tries to access length, since length is not defined within your function, the JavaScript engine will look up the length variable in the global context (because of closure).

If you executed this in Node, you'll notice that an error gets thrown because the global context in Node doesn't have a length property.

wmock
  • 5,382
  • 4
  • 40
  • 62
  • By variable context, do you mean that my "length" is grabbing a value assigned to it outside of the function? Because, this is the only place I have declared length. In fact, that's all of my code. – Clifford Fajardo Dec 29 '14 at 04:14
  • Yes, this is how all JavaScript functions work. When you execute a function, the JavaScript engine will first try to resolve all variable references within the scope of the function. When it doesn't find a variable reference within the scope of the function, it moves up to the function's lexically scoped context. In this case, because the function is defined in the global scope, the JavaScript engine will look for the length variable in the global scope. The reason it doesn't throw an error is because browsers have a length property defined in the global scope. Hope this helps! – wmock Dec 29 '14 at 04:18
  • 1
    Yes, it is referring to window.length. The confusion you're having is most likely due to your understanding of how variables get referenced when executing JavaScript functions. When you actually invoke your function, the JavaScript engine will try to look up the length reference within the scope of the function. When the engine doesn't find length there (since you never defined length inside your function), the engine goes to the parent lexical scope, which happens to be the global scope. Within the global scope, there is a length property defined. The global length property is window.length. – wmock Dec 29 '14 at 04:31
  • I HIGHLY recommend this resource https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/README.md#you-dont-know-js-scope--closures if you're interested in learning more about scope in JavaScript! – wmock Dec 29 '14 at 04:34
1

You have not defined the length variable locally inside of your function. As a result when you invoke this function it looks up into its parent scope to find the value of the length variable.

Assuming this function is defined in the global scope then it would look up into the window object to find the value of length. In this case that would be window.length, which refers to the number of iframes in the current window. You can read more about window.length here:

That being said, we can fix this by modifying your original function. Since your function is trying to calculate the area of a rectangle we need to modify your original function so it calculates distance using both of your arguments. I would advise doing the following:

function areaRectangle(width, height) {
  aRectangle = width * height; // notice we changed the second variable to height
  console.log("The area of the rectangle is: " + aRectangle);
}
areaRectangle(10, 7); // This will result in 70.
ravendano
  • 346
  • 1
  • 3
1

You access the closest related parent scope variable when you don't declare it in the current block of code, so when you refer to length, if no declared variable exists it is resolved to the global scope in most execution enviroments. In the browser that context is window, so you are actually referencing window.length.

Realizing that answer is a little convoluted, here is an example of how it can resolve to local or parent scope variables.

If you did this,

<script>
    var length = "potato";
    function areaRectangle(width, height) {
        aRectangle = width * length;
        console.log("The area of the rectangle is: " + aRectangle);
    }
    areaRectangle(10, 7); // My number results in 0
</script>

you would get this in the console;

The area of the rectangle is: NaN

so if you did this,

<script>
    var length = "potato";
    function areaRectangle(width, height) {
  var length = height;
        aRectangle = width * length ;
        console.log("The area of the rectangle is: " + aRectangle);
    }
    areaRectangle(10, 7); // results is 70
</script>

you would get this in the console:

The area of the rectangle is: 70

This is because the variable length is declared in the local or another closer visible scope.

In your code, the variable is being bound to the global object (which is window in the browser), resulting in window.length.

konkked
  • 3,161
  • 14
  • 19
1

length derives from window.length and that is a property that defines how many frames are within a given window context. 0 = no frames, 1 = 1 frame, N = N frames.

https://developer.mozilla.org/en-US/docs/Web/API/Window.length

This is not to be confused with the given property of Object.length, since window inherits from Object (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Properties).

Matt Lo
  • 5,442
  • 1
  • 21
  • 21
0

length is 0 at this time. It also happens to exist in global scope (window). I think you may have confused your variable names.

You are allowed to use the variable named length as an argument, but you don't do that here, so it uses the one in the global scope.

This is what you want:

function areaRectangle(width, height) 
{
    aRectangle = width * height;

    console.log("The area of the rectangle is: " + aRectangle);
}

areaRectangle(10, 7);
Ryan
  • 14,392
  • 8
  • 62
  • 102
0

You try using use strict:

function areaRectangle(width, height) {
  'use strict';
  aRectangle = width * length;
  console.log("The area of the rectangle is: " + aRectangle);
}
areaRectangle(10, 7);
Open console...