JavaScript/Syntax examples
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.varx;// Variables can be manually set to `undefined` like soletx2=undefined;// Declares a block-scoped variable named `y`, and implicitly sets it to// `undefined`. The `let` keyword was introduced in ECMAScript 2015.lety;// 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`.constz="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.letmyNumber=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.constmyElem=document.createElement('span');// Attributes like classes and the id can be set as wellmyElem.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 <body> in the HTMLdocument.body.appendChild(myElem);// Elements can be imperatively grabbed with querySelector for one element, or querySelectorAll for multiple elements that can be looped with forEachdocument.querySelector('.class');// Selects the first element with the "class" classdocument.querySelector('#id');// Selects the first element with an `id` of "id"document.querySelector('[data-other]');// Selects the first element with the "data-other" attributedocument.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:
functionfactorial(n){// Checking the argument for legitimacy. Factorial is defined for positive integers.if(isNaN(n)){console.error("Non-numerical argument not allowed.");returnNaN;// The special value: Not a Number}if(n===0)return1;// 0! = 1if(n<0)returnundefined;// 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.constrecursivelyCompute=a=>a>1?a*recursivelyCompute(a-1):1;// Note the use of the ternary operator `?`.returnrecursivelyCompute(n);}factorial(3);// Returns 6
An anonymous function (or lambda):
constcounter=function(){letcount=0;returnfunction(){return++count;}};constx=counter();x();// Returns 1x();// Returns 2x();// 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.constlong_example=(input1,input2)=>{console.log("Hello, World!");constoutput=input1+input2;returnoutput;};// If there are no braces, the arrow function simply returns the expression// So here it's (input1 + input2)constshort_example=(input1,input2)=>input1+input2;long_example(2,3);// Prints "Hello, World!" and returns 5short_example(2,5);// Returns 7// If an arrow function has only one parameter, the parentheses can be removed.constno_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.letthree=((a,b)=>a+b)(1,2);constgenerate_multiplier_function=a=>(b=>isNaN(b)||!b?a:a*=b);constfive_multiples=generate_multiplier_function(5);// The supplied argument "seeds" the expression and is retained by a.five_multiples(1);// Returns 5five_multiples(3);// Returns 15five_multiples(4);// Returns 60
In JavaScript, objects can be created as instances of a class.
Object class example:
classBall{constructor(radius){this.radius=radius;this.area=Math.PI*(radius**2);}// Classes (and thus objects) can contain functions known as methodsshow(){console.log(this.radius);}};constmyBall=newBall(5);// Creates a new instance of the ball object with radius 5myBall.radius++;// Object properties can usually be modified from the outsidemyBall.show();// Using the inherited "show" function logs "6"
In JavaScript, objects can be instantiated directly from a function.
Object functional example:
functionBall(radius){constarea=Math.PI*(radius**2);constobj={radius,area};// Objects are mutable, and functions can be added as properties.obj.show=()=>console.log(obj.radius);returnobj;};constmyBall=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]
functionsum(){letx=0;for(leti=0;i<arguments.length;++i)x+=arguments[i];returnx;}sum(1,2);// Returns 3sum(1,2,3);// Returns 6// As of ES6, using the rest operator.functionsum(...args){returnargs.reduce((a,b)=>a+b);}sum(1,2);// Returns 3sum(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:
letcounter=(function(){leti=0;// Private propertyreturn{// Public methodsget:function(){alert(i);},set:function(value){i=value;},increment:function(){alert(++i);}};})();// Modulecounter.get();// Returns 0counter.set(6);counter.increment();// Returns 7counter.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(){yield1;yield2;}function*dynamicCounter(){letcount=0;while(true){// It is not recommended to utilize while true loops in most cases.yield++count;}}// Instancesconstcounter1=rawCounter();constcounter2=dynamicCounter();// Implementationcounter1.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 exportedletsum=(a,b)=>{returna+b;}// Export variablesexportletname='Alice';exportletage=23;// Export named functionsexportfunctionadd(num1,num2){returnnum1+num2;}// Export classexportclassMultiplication{constructor(num1,num2){this.num1=num1;this.num2=num2;}add(){returnsum(this.num1,this.num2);}}
Import example:
// Import one propertyimport{add}from'./mymodule.js';console.log(add(1,2));//> 3// Import multiple propertiesimport{name,age}from'./mymodule.js';console.log(name,age);//> "Alice", 23// Import all properties from a moduleimport*from'./module.js'console.log(name,age);//> "Alice", 23console.log(add(1,2));//> 3
More advanced example
[edit | edit source]This sample code displays various JavaScript features.
/* Finds the lowest common multiple (LCM) of two numbers */functionLCMCalculator(x,y){// constructor functionif(isNaN(x*y))thrownewTypeError("Non-numeric arguments not allowed.");constcheckInt=function(x){// inner functionif(x%1!==0)thrownewTypeError(x+"is not an integer");returnx;};this.a=checkInt(x)// semicolons ^^^^ are optional, a newline is enoughthis.b=checkInt(y);}// The prototype of object instances created by a constructor is// that constructor's "prototype" property.LCMCalculator.prototype={// object literalconstructor:LCMCalculator,// when reassigning a prototype, set the constructor property appropriatelygcd:function(){// method that calculates the greatest common divisor// Euclidean algorithm:leta=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.gcdthis['gcd']=function(){returna;};returna;},// 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 issuesletlcm=this.a/this.gcd()*this.b;// Only need to calculate lcm once, so "redefine" this method.this.lcm=function(){returnlcm;};returnlcm;},// Methods can also be declared using ES6 syntaxtoString(){// Using both ES6 template literals and the (+) operator to concatenate valuesreturn`LCMCalculator: a = ${this.a}, b = `+this.b;}};// Define generic output function; this implementation only works for Web browsersfunctionoutput(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 functionreturnnewLCMCalculator(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);functionprintResult(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 = 56LCMCalculator: a = 21, b = 56, gcd = 7, lcm = 168LCMCalculator: a = 25, b = 55, gcd = 5, lcm = 275LCMCalculator: a = 22, b = 58, gcd = 2, lcm = 638
References
[edit | edit source]- ↑"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.