144 | Chapter 7: Variables 144 | Chapter 7: Variables

144 | Chapter 7: Variables 144 | Chapter 7: Variables

isset($a) returns false.

The PHP unset() API function can be called on any variable, including array values, array variables themselves, or normal, nonarray variables. The Node.js delete keyword is not as flexible.

The Node.js delete keyword has a boolean return value. If it could delete the variable, the Node.js delete keyword will return true. If it could not delete the variable, the Node.js delete keyword returns false. Ordinary object properties, such as those prop‐ erties added to a Node.js object that implements an associative array, can be deleted. That is why the Node.js delete keyword works as a substitute for the PHP unset() API function when it is applied to PHP associative arrays. However, built-in properties, such as the length property on Node.js indexed arrays, and ordinary variables will return false if the Node.js delete keyword is called upon them. The Node.js delete keyword has no effect on these other types of variables.

Built-in properties, such as the length property on Node.js indexed arrays, should not have the Node.js delete keyword called upon them. This is a coding error. There is no reason that PHP code that is converted to Node.js should try to call the PHP unset() API or the Node.js delete keyword on built-in properties of arrays or objects.

It is possible, though, that the PHP unset() API function could be called on an ordinary variable in well-written PHP code. In PHP, an ordinary variable is not declared; the PHP engine creates it when it is first used. But in Node.js, an ordinary variable is declared with the var keyword. The var keyword, by its use, assigns a scope to the variable and requires that the variable exist throughout that scope. As you will recall, a scope is an area of source code where the variable name refers to the specific variable created in a var statement. The Node.js delete keyword cannot work because that would violate the implied contract that the var keyword creates. There is no corresponding unvar keyword; a Node.js variable is always valid inside its scope.

Even though an ordinary variable in Node.js cannot be deleted, the variable itself can

be set to the “undefined” type and its value can be the “undefined” value. The variable still exists, but the type and the value is undefined. This is the next best thing to being able to delete a Node.js variable.

It is fortuitous that Node.js itself uses this same solution for the indexes and values in sparse arrays that should not exist. In sparse arrays, the unused keys have the “unde‐ fined” type and their corresponding values take on the “undefined” value.

The following find-and-replace action will replace PHP unset() API function calls with

a Node.js statement that sets the Node.js variable to undefined:

Undefined Variables | 145

Operation: "Find/Replace" in Eclipse PDT Find: unset\((.*)\) Replace: $1 = undefined Options: Regular expressions, Wrap search Action: Find, then Replace/Find

At each occurrence, the PHP unset() API function call should only be replaced if an ordinary Node.js variable that was created using the var keyword is passed as an argu‐ ment. Otherwise, the action should not be executed.

After the previous find-and-replace action and the similar find-and-replace action for associative arrays are executed, a “deleted” value or variable for any array variable or an ordinary variable will either not exist or have the “undefined” type and be set to the “undefined” value.

The PHP isset() API function determines the existence of a variable. If the variable exists, it returns true; otherwise, it returns false. The PHP isset() API function can

be applied to array values or ordinary variables. As it turns out, testing for the Node.js undefined type is equivalent to the PHP isset()

API function in terms of PHP to Node.js conversion. Whether a Node.js value is actually deleted or is set to the undefined value, the Node.js

typeof operator can evaluate it and will return undefined as its type. The typeof operator does not distinguish between these two different states, even though the Node.js delete operator does.

The following Node.js code demonstrates that used and unused values in a sparse array can be distinguished using the Node.js typeof keyword:

var a = [ ]; a [ 1 ] = 'red' ; console . log ( 'used value in sparse array exists: '

+ (( typeof a [ 1 ]) != 'undefined' ));

console . log ( 'unused value in sparse array exists: '

+ (( typeof a [ 0 ]) != 'undefined' ));

The output of the Node.js code proves that testing a Node.js sparse array key to see if it is of the undefined type is equivalent to calling the PHP isset() function on the cor‐ responding PHP code:

used value in sparse array exists: true unused value in sparse array exists: false

The following Node.js code demonstrates that used and unused keys in a Node.js as‐ sociative array can be distinguished using the Node.js typeof keyword:

var a = { model : false };

console . log ( 'known associative array key exists: '

+ (( typeof a [ 'model' ]) != 'undefined' ));

console . log ( 'unknown associative array key exists: '

146 | Chapter 7: Variables

+ (( typeof a [ 'color' ]) != 'undefined' ));

delete a [ 'model' ]; console . log ( 'deleted associative array key exists: '

+ (( typeof a [ 'model' ]) != 'undefined' ));

The output proves that it works for Node.js objects, which is our implementation of a PHP-style associative array:

known associative array key exist: true unknown associative array key exist: false deleted associative array key exist: false

The following Node.js code demonstrates that Node.js ordinary variables set to the undefined value array can be distinguished using the Node.js typeof keyword as ex‐ pected:

var a = false ; console . log ( 'ordinary variable exists: ' + (( typeof a ) != 'undefined' )); a = undefined ; console . log ( 'ordinary undefined variable exists: ' + (( typeof a ) != 'undefined' ));

The output proves that it works for Node.js objects, which is our implementation of a PHP-style associative array:

ordinary variable exists: true ordinary undefined variable exists: false

This Node.js test code proves that PHP isset() API function calls can always be con‐ verted into Node.js typeof keyword tests.

As a result, converting the PHP isset() API function calls into Node.js can be done by executing this find-and-replace action:

Operation: "Find/Replace" in Eclipse PDT Find: isset\((.*)\) Replace: ((typeof $1) != 'undefined') Options: Regular expressions, Wrap search Action: Replace All

As expected, a quick-and-dirty alternative is to implement the PHP isset() API func‐ tion in Node.js:

function isset ( a ) {

return (( typeof $1 ) != 'undefined' );

The only caveat to these two ways of converting the PHP isset() API function into Node.js is that variables declared with the var keyword must be in scope. If the Node.js variable is not in scope, the Node.js server will exit with a stack trace and emit a message. The following message was emitted because of an out-of-scope v variable:

ReferenceError: v is not defined

Undefined Variables | 147

With the variable types and various variable-related APIs converted from PHP to Node.js, there is a final issues to address: variable scoping.