Programming languages can be classified as statically typed languages or dynamically typed languages according to type checking is performed during compile-time or runtime.
Variables of static languages have types, such as Java, C/C++, Scala, and so on. Take Java for example:
int number = 10;In the above example, the type of the variable number is int, and the type of id is String. While assigning a value to a variable, they should have a consistent type or a compiler error will happen. For example, the following code would fail to compile because types of number and "caterpillar" don't match.
String id = "caterpillar";
int number = 10;JavaScript is a dynamic language. You don't have to declare a type while declaring a variable. Only values or objects have type information. Variables are just a handles for values or objects. For example:
number = "caterpillar";
var some = 10;Because variables don't have type information, the value of a variable can be any type. The type information of variables is only known at runtime through the referred objects and then the execution environment knows whether they have the required methods.
some = 'caterpillar';
Variables of static languages have type information. The greatest advantage of this feature is a compiler can check whether the type of a variable corresponds with the type of the assigned value. A lot of type mismatch errors can be caught at compile time. Dynamic languages, oppositely, can only discover type mismatch errors at runtime. Type checking at compiler time is the place where static languages are superior to dynamic languages.
Most static languages, however, require a type declaration while declaring a variable. This will result in tedious syntax easily. Take Java for example. If you want to store objects of different types in an array, an example is as follows:
Object[] objects = {"caterpillar", new Integer(100), new Date()};As for JavaScript, it needs relatively brief code to achieve the same goal. For example:
String name = (String) objects[0];
Integer score = (Integer) objects[1];
Data time = (Date) objects[2];
var objects = ['caterpillar', 100, new Date()];As far as coding speed is concerned, dynamic languages really have advantages compared with static languages.
var name = objects[0];
var score = objects[1];
var time = objects[2];
Go back to the discussion of JavaScript variable declarations. To declare a variable in JavaScript, you can use var. This has been seen previously. In fact, you can also declare variables without var, just specify a value to a variable name directly. The variable scope will be global. That's to say the value of the variable can be changed anywhere in the code, even in other functions. In fact, a variable without var creates a property on the global object. For example:
js> some = 10;
10
js> some;
10
js>
10
js> some;
10
js>
This is convenient but dangerous because it creates a property on the global object. The global object in a browser is the window object. In Rhino Shell, you can also use this to retrieve the global object. For example:
js> this.some;
10
js> this;
[Object global]
js>
10
js> this;
[Object global]
js>
Variables declared by var are available within the defined scope. Variables declared without var are properties of the global object, commonly known as the global scope. In the beginning, you can understand this concept as the following, if you write:
some = 10;You can imagine the interpreter will treat this statement as:
this.some = 10;For example, you can observe the difference between the following two variables, declared with and without var in the function func:
js> function func() {
> var x = 10;
> y = 20;
> }
js> func();
js> x;
js: "<stdin>", line 12: uncaught JavaScript runtime exception: ReferenceError: "x" is not defined.
at <stdin>:12
js> y;
20
js> this.y;
20
js>
> var x = 10;
> y = 20;
> }
js> func();
js> x;
js: "<stdin>", line 12: uncaught JavaScript runtime exception: ReferenceError: "x" is not defined.
at <stdin>:12
js> y;
20
js> this.y;
20
js>
The variable x is declared by var so it's not available outside the function. The variable y is declared without var so it's a property of the global object. That's why it's available from anywhere in the code.
If you use var to declare a variable outside of any function, it's equivalent to create a property on the global object. For example:
js> var x = 10;
js> this.x;
10
js>
js> this.x;
10
js>
Local variables will temporarily shadow global variables if they have the same name.
js> var x = 10;
js> function func() {
> var x = 20;
> print(x);
> }
js> func();
20
js> print(x);
10
js>
js> function func() {
> var x = 20;
> print(x);
> }
js> func();
20
js> print(x);
10
js>
You can use delete to delete properties on objects. Because variables declared without var are properties of the global object. To some extent, using delete to delete variables declared without var is so-called deleting variables. For example:
js> a = 20;
20
js> delete a;
true
js> a
js: "<stdin>", line 7: uncaught JavaScript runtime exception: ReferenceError: "a" is not defined.
at <stdin>:7
js> this.a;
js>
20
js> delete a;
true
js> a
js: "<stdin>", line 7: uncaught JavaScript runtime exception: ReferenceError: "a" is not defined.
at <stdin>:7
js> this.a;
js>
Note the above example, this.a will be undefined. Rhino shell, however, shows nothing for undefined. The delete operator returns true if it deletes a variable successfully and false if it fails. A variable declared by var cannot be deleted. For example:
js> var b = 10;
js> delete b;
false
js>
js> delete b;
false
js>
You can use var to repeat declaring the same variable, but don't overwrite the original value of the variable. For example:
js> var x = 10;
js> var x;
js> x
10
js> var x;
js> x
10
It should be noted that, if a variable is declared by var in a function, it is available from anywhere of the function. There's no so-called block scope. For example:
js> function func() {
> if(true) {
> var x = 10;
> }
> return x;
> }
js> func();
10
js>
> if(true) {
> var x = 10;
> }
> return x;
> }
js> func();
10
js>
Variables declared by var is available in the entire function. This will produce amazing results. The following example will get an interpreter error as expected.
js> function func() {
> print(m);
> }
js> func();
js: "<stdin>", line 210: uncaught JavaScript runtime exception: ReferenceError:
"m" is not defined.
at <stdin>:210 (func)
at <stdin>:210
js>
> print(m);
> }
js> func();
js: "<stdin>", line 210: uncaught JavaScript runtime exception: ReferenceError:
"m" is not defined.
at <stdin>:210 (func)
at <stdin>:210
js>
But the following example has no error:
js> function func() {
> print(m);
> var m = 10;
> print(m);
> }
js> func();
undefined
10
js>
> print(m);
> var m = 10;
> print(m);
> }
js> func();
undefined
10
js>
All variables declared by var are visible throughout the entire block of the function so, in the previous example, the variable m is available in the first statement of func, but the value is undefined.
Take a look at Scope chains if you are interested. The article talks about that variables declared by var are properties of call objects in the execution context where code is executed, so there's no so-called block scope.