comma Operator in JavaScript
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
Syntax
expr1, expr2, expr3...
Parameters
expr1
,expr2, expr3...
- Any expressions.
Description
You can use the comma operator when you want to include multiple expressions in a location that requires a single expression. The most common usage of this operator is to supply multiple parameters in a for
loop.
Examples
If a
is a 2-dimensional array with 10 elements on each side, the following code uses the comma operator to increment two variables at once.
The following code prints the values of the diagonal elements in the array:
for (var i = 0, j = 9; i <= 9; i++, j--)
console.log('a[' + i + '][' + j + '] = ' + a[i][j]);
Note that the comma in assignments such as the var
statement may appear not to have the normal effect of comma operators because they don’t exist within an expression. In the following example, a
is set to the value of b = 3
(which is 3), but the c = 4
expression still evaluates and its result returned to console (i.e., 4). This is due to operator precedence and associativity.
// Note that the following creates globals and is disallowed in strict mode.
a = b = 3, c = 4; // Returns 4 in console
console.log(a); // 3 (left-most)
x = (y = 5, z = 6); // Returns 6 in console
console.log(x); // 6 (right-most)
The comma operator is fully different from the comma within arrays, objects, and function arguments and parameters.
Processing and then returning
Another example that one could make with comma operator is processing before returning. As stated, only the last element will be returned but all others are going to be evaluated as well. So, one could do:
function myFunc() {
var x = 0;
return (x += 1, x); // the same as return ++x;
}
Grouping Operator in JavaScript
The grouping operator ( )
controls the precedence of evaluation in expressions.
Syntax
( )
Description
The grouping operator consists of a pair of parentheses around an expression or sub-expression to override the normal operator precedence so that expressions with lower precedence can be evaluated before an expression with higher priority. As it sounds it groups what’s inside of the parentheses
Examples
Overriding multiplication and division first, then addition and subtraction to evaluate addition first.
var a = 1;
var b = 2;
var c = 3;
// default precedence
a + b * c // 7
// evaluated by default like this
a + (b * c) // 7
// now overriding precedence
// addition before multiplication
(a + b) * c // 9
// which is equivalent to
a * c + b * c // 9
in Operator in JavaScript
The in
operator returns true
if the specified property is in the specified object or its prototype chain.
Syntax
prop in object
Parameters
prop
- A string or symbol representing a property name or array index (non-symbols will be coerced to strings).
object
- Object to check if it (or its prototype chain) contains the property with specified name.
Description
The following examples show some uses of the in
operator.
// Arrays
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
0 in trees // returns true
3 in trees // returns true
6 in trees // returns false
'bay' in trees // returns false (you must specify the
// index number, not the value at that index)
'length' in trees // returns true (length is an Array property)
Symbol.iterator in trees // returns true (arrays are iterable, works only in ES2015+)
// Predefined objects
'PI' in Math // returns true
// Custom objects
var mycar = {make: 'Honda', model: 'Accord', year: 1998};
'make' in mycar // returns true
'model' in mycar // returns true
You must specify an object on the right side of the in
operator. For example, you can specify a string created with the String
constructor, but you cannot specify a string literal.
var color1 = new String('green');
'length' in color1 // returns true
var color2 = 'coral';
// generates an error (color2 is not a String object)
'length' in color2
Using in
with deleted or undefined properties
If you delete a property with the delete
operator, the in
operator returns false
for that property.
var mycar = {make: 'Honda', model: 'Accord', year: 1998};
delete mycar.make;
'make' in mycar; // returns false
var trees = new Array('redwood', 'bay', 'cedar', 'oak', 'maple');
delete trees[3];
3 in trees; // returns false
If you set a property to undefined
but do not delete it, the in
operator returns true for that property.
var mycar = {make: 'Honda', model: 'Accord', year: 1998};
mycar.make = undefined;
'make' in mycar; // returns true
var trees = new Array('redwood', 'bay', 'cedar', 'oak', 'maple');
trees[3] = undefined;
3 in trees; // returns true
Inherited properties
The in
operator returns true
for properties in the prototype chain.
'toString' in {}; // returns true
Delete Operator in JavaScript
The JavaScript delete
operator removes a property from an object; if no more references to the same property are held, it is eventually released automatically.
Syntax
delete expression
where expression should evaluate to a property reference, e.g.:
delete object.property delete object['property']
Parameters
object
- The name of an object, or an expression evaluating to an object.
property
- The property to delete.
Return value
true
for all cases except when the property is an own non-configurable property, in which case, false
is returned in non-strict mode.
Exceptions
Throws Global_objects/SyntaxError
in strict mode if the property is an own non-configurable property.
Description
Unlike what common belief suggests, the delete
operator has nothing to do with directly freeing memory. Memory management is done indirectly via breaking references, see the memory management page for more details.
The delete
operator removes a given property from an object. On successful deletion, it will return true,
else false
will be returned. However, it is important to consider the following scenarios:
- If the property which you are trying to delete does not exist,
delete
will not have any effect and will returntrue
- If a property with the same name exists on the object’s prototype chain, then, after deletion, the object will use the property from the prototype chain (in other words,
delete
only has an effect on own properties). - Any property declared with
var
cannot be deleted from the global scope or from a function’s scope.- As such,
delete
cannot delete any functions in the global scope (whether this is part from a function definition or a function expression). - Functions which are part of an object (apart from the global scope) can be deleted with
delete
.
- As such,
- Any property declared with
let
orconst
cannot be deleted from the scope within which they were defined. - Non-configurable properties cannot be removed. This includes properties of built-in objects like
Math
,Array
,Object
and properties that are created as non-configurable with methods likeObject.defineProperty()
.
The following snippet gives a simple example:
var Employee = {
age: 28,
name: 'abc',
designation: 'developer'
}
console.log(delete Employee.name); // returns true
console.log(delete Employee.age); // returns true
// When trying to delete a property that does
// not exist, true is returned
console.log(delete Employee.salary); // returns true
Non-configurable properties
When a property is marked as non-configurable, delete
won’t have any effect, and will return false
. In strict mode this will raise a SyntaxError
.
var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false});
console.log(delete Employee.name); // returns false
var
, let
and const
create non-configurable properties that cannot be deleted with the delete
operator:
var nameOther = 'XYZ';
// We can access this global property using:
Object.getOwnPropertyDescriptor(window, 'nameOther');
// output: Object {value: "XYZ",
// writable: true,
// enumerable: true,
// configurable: false}
// Since "nameOther" is added using with the
// var keyword, it is marked as "non-configurable"
delete nameOther; // return false
In strict mode, this would have raised an exception.
Strict vs. non-strict mode
When in strict mode, if delete
is used on a direct reference to a variable, a function argument or a function name, it will throw a SyntaxError
.
Any variable defined with var
is marked as non-configurable. In the following example, salary
is non-configurable and cannot be deleted. In non-strict mode, the delete
operation will return false
.
function Employee() {
delete salary;
var salary;
}
Employee();
Let’s see how the same code behaves in strict mode. Instead of returning false
, the statement raises a SyntaxError
.
"use strict";
function Employee() {
delete salary; // SyntaxError
var salary;
}
// Similarly, any direct access to a function
// with delete will raise a SyntaxError
function DemoFunction() {
//some code
}
delete DemoFunction; // SyntaxError
Examples
// creates the property adminName on the global scope
adminName = 'xyz';
// creates the property empCount on the global scope
// Since we are using var, this is marked as non-configurable. The same is true of let and const.
var empCount = 43;
EmployeeDetails = {
name: 'xyz',
age: 5,
designation: 'Developer'
};
// adminName is a property of the global scope.
// It can be deleted since it is created without var.
// Therefore, it is configurable.
delete adminName; // returns true
// On the contrary, empCount is not configurable,
// since var was used.
delete empCount; // returns false
// delete can be used to remove properties from objects
delete EmployeeDetails.name; // returns true
// Even when the property does not exists, it returns "true"
delete EmployeeDetails.salary; // returns true
// delete does not affect built-in static properties
delete Math.PI; // returns false
// EmployeeDetails is a property of the global scope.
// Since it defined without "var", it is marked configurable
delete EmployeeDetails; // returns true
function f() {
var z = 44;
// delete doesn't affect local variable names
delete z; // returns false
}
delete
and the prototype chain
In the following example, we delete an own property of an object while a property with the same name is available on the prototype chain:
function Foo() {
this.bar = 10;
}
Foo.prototype.bar = 42;
var foo = new Foo();
// Returns true, since the own property
// has been deleted on the foo object
delete foo.bar;
// foo.bar is still available, since it
// is available in the prototype chain.
console.log(foo.bar);
// We delete the property on the prototype
delete Foo.prototype.bar;
// logs "undefined" since the property
// is no longer inherited
console.log(foo.bar);
Deleting array elements
When you delete an array element, the array length is not affected. This holds even if you delete the last element of the array.
When the delete
operator removes an array element, that element is no longer in the array. In the following example, trees[3]
is removed with delete
.
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];
if (3 in trees) {
// this does not get executed
}
If you want an array element to exist but have an undefined value, use the undefined
value instead of the delete
operator. In the following example, trees[3]
is assigned the value undefined, but the array element still exists:
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees[3] = undefined;
if (3 in trees) {
// this gets executed
}
If instead, you want to remove an array element by changing the contents of the array, use the splice
method. In the following example, trees[3]
is removed from the array completely using splice
:
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);
console.log(trees); // ["redwood", "bay", "cedar", "maple"]
New Operator in JavaScript
The new
operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function.
Syntax
new constructor[([arguments])]
Parameters
constructor
- A class or function that specifies the type of the object instance.
arguments
- A list of values that the
constructor
will be called with.
Description
Creating a user-defined object requires two steps:
- Define the object type by writing a function.
- Create an instance of the object with
new
.
To define an object type, create a function for the object type that specifies its name and properties. An object can have a property that is itself another object. See the examples below.
When the code new Foo(...)
is executed, the following things happen:
- A new object is created, inheriting from
Foo.prototype
. - The constructor function
Foo
is called with the specified arguments, and withthis
bound to the newly created object.new Foo
is equivalent tonew
Foo
()
, i.e. if no argument list is specified,Foo
is called without arguments. - The object returned by the constructor function becomes the result of the whole
new
expression. If the constructor function doesn’t explicitly return an object, the object created in step 1 is used instead. (Normally constructors don’t return a value, but they can choose to do so if they want to override the normal object creation process.)
You can always add a property to a previously defined object. For example, the statement car1.color = "black"
adds a property color
to car1
, and assigns it a value of “black
“. However, this does not affect any other objects. To add the new property to all objects of the same type, you must add the property to the definition of the Car
object type.
You can add a shared property to a previously defined object type by using the Function.prototype
property. This defines a property that is shared by all objects created with that function, rather than by just one instance of the object type. The following code adds a color property with value null
to all objects of type car
, and then overwrites that value with the string “black
” only in the instance object car1
. For more information, see prototype.
function Car() {}
car1 = new Car();
console.log(car1.color); // undefined
Car.prototype.color = null;
console.log(car1.color); // null
car1.color = 'black';
console.log(car1.color); // black
Examples
Object type and object instance
Suppose you want to create an object type for cars. You want this type of object to be called car
, and you want it to have properties for make, model, and year. To do this, you would write the following function:
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
Now you can create an object called mycar
as follows:
var mycar = new Car('Eagle', 'Talon TSi', 1993);
This statement creates mycar
and assigns it the specified values for its properties. Then the value of mycar.make
is the string “Eagle”, mycar.year
is the integer 1993, and so on.
You can create any number of car
objects by calls to new
. For example:
var kenscar = new Car('Nissan', '300ZX', 1992);
Object property that is itself another object
Suppose you define an object called person
as follows:
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
And then instantiate two new person
objects as follows:
var rand = new Person('Rand McNally', 33, 'M');
var ken = new Person('Ken Jones', 39, 'M');
Then you can rewrite the definition of car
to include an owner
property that takes a person object, as follows:
function Car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
}
To instantiate the new objects, you then use the following:
var car1 = new Car('Eagle', 'Talon TSi', 1993, rand);
var car2 = new Car('Nissan', '300ZX', 1992, ken);
Instead of passing a literal string or integer value when creating the new objects, the above statements pass the objects rand
and ken
as the parameters for the owners. To find out the name of the owner of car2
, you can access the following property:
car2.owner.name
Void Operator in JavaScript
The void
operator evaluates the given expression
and then returns undefined
.
Syntax
void expression
Description
This operator allows evaluating expressions that produce a value into places where an expression that evaluates to undefined
is desired.
The void
operator is often used merely to obtain the undefined
primitive value, usually using “void(0)
” (which is equivalent to “void 0
“). In these cases, the global variable undefined
can be used instead (assuming it has not been assigned to a non-default value).
Immediately Invoked Function Expressions
When using an immediately-invoked function expression, void
can be used to force the function
keyword to be treated as an expression instead of a declaration.
void function iife() {
var bar = function () {};
var baz = function () {};
var foo = function () {
bar();
baz();
};
var biz = function () {};
foo();
biz();
}();
JavaScript URIs
When a browser follows a javascript:
URI, it evaluates the code in the URI and then replaces the contents of the page with the returned value, unless the returned value is undefined
. The void
operator can be used to return undefined
. For example:
<a href="javascript:void(0);">
Click here to do nothing
</a>
<a href="javascript:void(document.body.style.backgroundColor='green');">
Click here for green background
</a>
Note, however, that the javascript:
pseudo protocol is discouraged over other alternatives, such as unobtrusive event handlers.