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 so letx2=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 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 <body> 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:
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! = 1 if(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 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. 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 5 short_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 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:
classBall{ 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); } }; constmyBall=newBall(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:
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 3 sum(1,2,3);// Returns 6 // As of ES6, using the rest operator. functionsum(...args){ returnargs.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:
letcounter=(function(){ leti=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(){ yield1; yield2; } function*dynamicCounter(){ letcount=0; while(true){ // It is not recommended to utilize while true loops in most cases. yield++count; } } // Instances constcounter1=rawCounter(); constcounter2=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 letsum=(a,b)=>{ returna+b; } // Export variables exportletname='Alice'; exportletage=23; // Export named functions exportfunctionadd(num1,num2){ returnnum1+num2; } // Export class exportclassMultiplication{ constructor(num1,num2){ this.num1=num1; this.num2=num2; } add(){ returnsum(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
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 function if(isNaN(x*y))thrownewTypeError("Non-numeric arguments not allowed."); constcheckInt=function(x){// inner function if(x%1!==0) thrownewTypeError(x+"is not an integer"); returnx; }; 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: 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.gcd this['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 issues letlcm=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 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 functionoutput(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 returnnewLCMCalculator(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 = 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
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.