Jump to content

JavaScript/Syntax examples

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.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]
  1. "var – JavaScript". The Mozilla Developer Network. Archived from the original on December 23, 2012. Retrieved December 22, 2012.
  2. "let". MDN web docs. Mozilla. Archived from the original on May 28, 2019. Retrieved June 27, 2018.
  3. "const". MDN web docs. Mozilla. Archived from the original on June 28, 2018. Retrieved June 27, 2018.
  4. "ECMAScript Language Specification – ECMA-262 Edition 5.1". Ecma International. Archived from the original on November 26, 2012. Retrieved December 22, 2012.
  5. "console". Mozilla Developer Network. Mozilla. Archived from the original on February 28, 2013. Retrieved April 6, 2013.
  6. "arguments". Mozilla Developer Network. Mozilla. Archived from the original on April 13, 2013. Retrieved April 6, 2013.
  7. "function* - JavaScript | MDN". developer.mozilla.org. Retrieved 2022-09-27.
  8. "JavaScript modules". MDN Web Docs. Mozilla. Archived from the original on 17 July 2022. Retrieved 28 July 2022.
close