JavaScript/Syntax examples - Wikibooks, open books for an open world (original) (raw)
From Wikibooks, open books for an open world
These are simple examples of JavaScript syntax.
Variables in JavaScript can be defined using either the var
,[1] let
[2] or const
[3] keywords. Variables defined without keywords will be defined at the global scope.
// Declares a function-scoped variable named x
, and implicitly assigns the
// special value undefined
to it. Variables without value are automatically
// set to undefined.
// var is generally considered bad practice and let and const are usually preferred.
var x;
// Variables can be manually set to undefined
like so
let x2 = undefined;
// Declares a block-scoped variable named y
, and implicitly sets it to
// undefined
. The let
keyword was introduced in ECMAScript 2015.
let y;
// Declares a block-scoped, un-reassignable variable named z
, and sets it to
// a string literal. The const
keyword was also introduced in ECMAScript 2015,
// and must be explicitly assigned to.
// The keyword const
means constant, hence the variable cannot be reassigned
// as the value is constant
.
const z = "this value cannot be reassigned!";
// Declares a global-scoped variable and assigns 3. This is generally considered // bad practice, and will not work if strict mode is on. t = 3;
// Declares a variable named myNumber
, and assigns a number literal (the value
// 2
) to it.
let myNumber = 2;
// Reassigns myNumber
, setting it to a string literal (the value "foo"
).
// JavaScript is a dynamically-typed language, so this is legal.
myNumber = "foo";
Note the comments in the examples above, all of which were preceded with two forward slashes.
There is no built-in input/output functionality in JavaScript, instead it is provided by the run-time environment. The ECMAScript specification in edition 5.1 mentions that "there are no provisions in this specification for input of external data or output of computed results".[4]However, most runtime environments have a console
object that can be used to print output.[5] Here is a minimalist "Hello, World!" program in JavaScript in a runtime environment with a console object:
console.log("Hello, World!");
In HTML documents, a program like this is required for an output:
// Text nodes can be made using the "write" method. // This is frowned upon, as it can overwrite the document if the document is fully loaded. document.write('foo');
// Elements can be made too. First, they have to be created in the DOM. const myElem = document.createElement('span');
// Attributes like classes and the id can be set as well myElem.classList.add('foo'); myElem.id = 'bar';
// After setting this, the tag will look like this: <span class="foo" id="bar" data-attr="baz"></span>
myElem.setAttribute('data-attr', 'baz'); // Which could also be written as myElem.dataset.attr = 'baz'
// Finally append it as a child element to the in the HTML document.body.appendChild(myElem);
// Elements can be imperatively grabbed with querySelector for one element, or querySelectorAll for multiple elements that can be looped with forEach
document.querySelector('.class'); // Selects the first element with the "class" class
document.querySelector('#id'); // Selects the first element with an id
of "id"
document.querySelector('[data-other]'); // Selects the first element with the "data-other" attribute
document.querySelectorAll('.multiple'); // Returns an Array-like NodeList of all elements with the "multiple" class
A simple recursive function to calculate the factorial of a natural number:
function factorial(n) {
// Checking the argument for legitimacy. Factorial is defined for positive integers.
if (isNaN(n)) {
console.error("Non-numerical argument not allowed.");
return NaN; // The special value: Not a Number
}
if (n === 0)
return 1; // 0! = 1
if (n < 0)
return undefined; // Factorial of negative numbers is not defined.
if (n % 1) {
console.warn(${n} will be rounded to the closest integer. For non-integers consider using gamma function instead.
);
n = Math.round(n);
}
// The above checks need not be repeated in the recursion, hence defining the actual recursive part separately below.
// The following line is a function expression to recursively compute the factorial. It uses the arrow syntax introduced in ES6.
const recursivelyCompute = a => a > 1 ? a * recursivelyCompute(a - 1) : 1; // Note the use of the ternary operator `?`.
return recursivelyCompute(n);
}
factorial(3); // Returns 6
An anonymous function (or lambda):
const counter = function() { let count = 0; return function() { return ++count; } };
const x = counter(); x(); // Returns 1 x(); // Returns 2 x(); // Returns 3
This example shows that, in JavaScript, function closures capture their non-local variables by reference.
Arrow functions were first introduced in 6th Edition – ECMAScript 2015. They shorten the syntax for writing functions in JavaScript. Arrow functions are anonymous, so a variable is needed to refer to them in order to invoke them after their creation, unless surrounded by parenthesis and executed immediately.
Example of arrow function:
// Arrow functions let us omit the function
keyword.
// Here long_example
points to an anonymous function value.
const long_example = (input1, input2) => {
console.log("Hello, World!");
const output = input1 + input2;
return output;
};
// If there are no braces, the arrow function simply returns the expression // So here it's (input1 + input2) const short_example = (input1, input2) => input1 + input2;
long_example(2, 3); // Prints "Hello, World!" and returns 5 short_example(2, 5); // Returns 7
// If an arrow function has only one parameter, the parentheses can be removed. const no_parentheses = input => input + 2;
no_parentheses(3); // Returns 5
// An arrow function, like other function definitions, can be executed in the same statement as they are created. // This is useful when writing libraries to avoid filling the global scope, and for closures. let three = ((a, b) => a + b) (1, 2);
const generate_multiplier_function = a => (b => isNaN(b) || !b ? a : a*=b); const five_multiples = generate_multiplier_function(5); // The supplied argument "seeds" the expression and is retained by a. five_multiples(1); // Returns 5 five_multiples(3); // Returns 15 five_multiples(4); // Returns 60
In JavaScript, objects can be created as instances of a class.
Object class example:
class Ball {
constructor(radius) { this.radius = radius; this.area = Math.PI * ( radius ** 2 ); }
// Classes (and thus objects) can contain functions known as methods show() { console.log(this.radius); } };
const myBall = new Ball(5); // Creates a new instance of the ball object with radius 5 myBall.radius++; // Object properties can usually be modified from the outside myBall.show(); // Using the inherited "show" function logs "6"
In JavaScript, objects can be instantiated directly from a function.
Object functional example:
function Ball(radius) {
const area = Math.PI * ( radius ** 2 ); const obj = { radius, area };
// Objects are mutable, and functions can be added as properties. obj.show = () => console.log(obj.radius); return obj; };
const myBall = Ball(5); // Creates a new ball object with radius 5. No "new" keyword needed. myBall.radius++; // The instance property can be modified. myBall.show(); // Using the "show" function logs "6" - the new instance value.
Variadic function demonstration (arguments
is a special variable):[6]
function sum() { let x = 0;
for (let i = 0; i < arguments.length; ++i)
x += arguments[i];
return x;
}
sum(1, 2); // Returns 3 sum(1, 2, 3); // Returns 6
// As of ES6, using the rest operator. function sum(...args) { return args.reduce((a, b) => a + b); }
sum(1, 2); // Returns 3 sum(1, 2, 3); // Returns 6
Immediately-invoked function expressions are often used to create closures. Closures allow gathering properties and methods in a namespace and making some of them private:
let counter = (function() { let i = 0; // Private property
return { // Public methods
get: function() {
alert(i);
},
set: function(value) {
i = value;
},
increment: function() {
alert(++i);
}
};
})(); // Module
counter.get(); // Returns 0 counter.set(6); counter.increment(); // Returns 7 counter.increment(); // Returns 8
Generator objects (in the form of generator functions) provide a function which can be called, exited, and re-entered while maintaining internal context (statefulness).[7]
function* rawCounter() { yield 1; yield 2; }
function* dynamicCounter() { let count = 0; while (true) { // It is not recommended to utilize while true loops in most cases. yield ++count; } }
// Instances const counter1 = rawCounter(); const counter2 = dynamicCounter();
// Implementation counter1.next(); // {value: 1, done: false} counter1.next(); // {value: 2, done: false} counter1.next(); // {value: undefined, done: true}
counter2.next(); // {value: 1, done: false} counter2.next(); // {value: 2, done: false} counter2.next(); // {value: 3, done: false} // ...infinitely
JavaScript can export and import from modules:[8]
Export example:
/* mymodule.js */ // This function remains private, as it is not exported let sum = (a, b) => { return a + b; }
// Export variables export let name = 'Alice'; export let age = 23;
// Export named functions export function add(num1, num2) { return num1 + num2; }
// Export class export class Multiplication { constructor(num1, num2) { this.num1 = num1; this.num2 = num2; }
add() {
return sum(this.num1, this.num2);
}
}
Import example:
// Import one property import { add } from './mymodule.js'; console.log(add(1, 2)); //> 3
// Import multiple properties import { name, age } from './mymodule.js'; console.log(name, age); //> "Alice", 23
// Import all properties from a module import * from './module.js' console.log(name, age); //> "Alice", 23 console.log(add(1,2)); //> 3
This sample code displays various JavaScript features.
/* Finds the lowest common multiple (LCM) of two numbers / function LCMCalculator(x, y) { // constructor function if (isNaN(xy)) throw new TypeError("Non-numeric arguments not allowed."); const checkInt = function(x) { // inner function if (x % 1 !== 0) throw new TypeError(x + "is not an integer");
return x;
};
this.a = checkInt(x)
// semicolons ^^^^ are optional, a newline is enough
this.b = checkInt(y);
} // The prototype of object instances created by a constructor is // that constructor's "prototype" property. LCMCalculator.prototype = { // object literal constructor: LCMCalculator, // when reassigning a prototype, set the constructor property appropriately gcd: function() { // method that calculates the greatest common divisor // Euclidean algorithm: let a = Math.abs(this.a), b = Math.abs(this.b), t;
if (a < b) {
// swap variables
// t = b; b = a; a = t;
[a, b] = [b, a]; // swap using destructuring assignment (ES6)
}
while (b !== 0) {
t = b;
b = a % b;
a = t;
}
// Only need to calculate GCD once, so "redefine" this method.
// (Actually not redefinition—it's defined on the instance itself,
// so that this.gcd refers to this "redefinition" instead of LCMCalculator.prototype.gcd.
// Note that this leads to a wrong result if the LCMCalculator object members "a" or "b" are altered afterwards.)
// Also, 'gcd' === "gcd", this['gcd'] === this.gcd
this['gcd'] = function() {
return a;
};
return a;
},
// Object property names can be specified by strings delimited by double (") or single (') quotes.
"lcm": function() {
// Variable names do not collide with object properties, e.g., |lcm| is not |this.lcm|.
// not using |this.a*this.b| to avoid FP precision issues
let lcm = this.a / this.gcd() * this.b;
// Only need to calculate lcm once, so "redefine" this method.
this.lcm = function() {
return lcm;
};
return lcm;
},
// Methods can also be declared using ES6 syntax
toString() {
// Using both ES6 template literals and the (+) operator to concatenate values
return `LCMCalculator: a = ${this.a}, b = ` + this.b;
}
};
// Define generic output function; this implementation only works for Web browsers function output(x) { document.body.appendChild(document.createTextNode(x)); document.body.appendChild(document.createElement('br')); }
// Note: Array's map() and forEach() are defined in JavaScript 1.6. // They are used here to demonstrate JavaScript's inherent functional nature. [ [25, 55], [21, 56], [22, 58], [28, 56] ].map(function(pair) { // array literal + mapping function return new LCMCalculator(pair[0], pair[1]); }).sort((a, b) => a.lcm() - b.lcm()) // sort with this comparative function; => is a shorthand form of a function, called "arrow function" .forEach(printResult);
function printResult(obj) { output(obj + ", gcd = " + obj.gcd() + ", lcm = " + obj.lcm()); }
The following output should be displayed in the browser window.
LCMCalculator: a = 28, b = 56, gcd = 28, lcm = 56 LCMCalculator: a = 21, b = 56, gcd = 7, lcm = 168 LCMCalculator: a = 25, b = 55, gcd = 5, lcm = 275 LCMCalculator: a = 22, b = 58, gcd = 2, lcm = 638
- ↑ "var – JavaScript". The Mozilla Developer Network. Archived from the original on December 23, 2012. Retrieved December 22, 2012.
- ↑ "let". MDN web docs. Mozilla. Archived from the original on May 28, 2019. Retrieved June 27, 2018.
- ↑ "const". MDN web docs. Mozilla. Archived from the original on June 28, 2018. Retrieved June 27, 2018.
- ↑ "ECMAScript Language Specification – ECMA-262 Edition 5.1". Ecma International. Archived from the original on November 26, 2012. Retrieved December 22, 2012.
- ↑ "console". Mozilla Developer Network. Mozilla. Archived from the original on February 28, 2013. Retrieved April 6, 2013.
- ↑ "arguments". Mozilla Developer Network. Mozilla. Archived from the original on April 13, 2013. Retrieved April 6, 2013.
- ↑ "function* - JavaScript | MDN". developer.mozilla.org. Retrieved 2022-09-27.
- ↑ "JavaScript modules". MDN Web Docs. Mozilla. Archived from the original on 17 July 2022. Retrieved 28 July 2022.