Because of its multi-paradigm characteristic, JS supports event-driven, functional, and imperative (which includes object-oriented and prototype-based) programming styles; making it quite diverse. Its API is capable of working with text, arrays, dates, regular expressions, and basic Document Object Model (DOM) manipulation; however, it is not capable of doing any Input/Output (I/O) operations; such as networking, storage, or graphics facilities. This is because the language itself does not include this functionality and instead, relies upon the host environment it is embedded in for these functions.
Initially, the language was implemented on the client-side of web browsers for the sake of the end-user; however, in the modern times, JS engines have expanded and can be implemented into many other types of host software; including server-side databases, runtime environments to allow use of JS in mobile and desktop application development, and even non-web word processors and PDF software.
To build on this, the language is Dynamically Typed; meaning, that when declaring variables, there is no need to identify specific variable types as each variable change with ease; such as a variable which once held a string now holding an integer. It also has Dynamic Runtime Evaluation using a special function, eval which allows string-provided statements to be executed at runtime.
It's prototype-based characteristic allows for it to be object-oriented and almost entirely object-based. Within the language, an object is designed as an associative array that has been augmented with a prototype. Through this method, each string key property of the array is a property of the object and they can be identified through either dot notation (object.property = 10) or bracket notation (object[property] = 10). These properties can be added, rebounded, or deleted at runtime and most can all be enumerated through the use of a for-in loop on an object. Something to note is that while this is also defined as an object-oriented characteristic, JS uses prototypes to achieve this, unlike other object-oriented languages which use classes for inheritance. This means that functions double as object constructors to create prototypes and as methods to manipulate the properties of prototypes.
It also handles delegation both implicitly and explicitly which allows for the special this keyword of an object to gain additional behavior within its function body through the function-based implementation of Role patterns such as Traits and Mixins. Along with this, object composition and inheritance are also achieved through its support of both implicit and explicit delegation.
Moreover, its support for regular expressions puts a lot of power in the hands of developers to manipulate text in a sophisticated fashion while its variadic functions allow for an indefinite number of parameters to be passed to a function. It even allows for array and objects literals to be created using a succinct syntax shortcut; much like every other scripting language.
Applications and Uses
Misplaced trust in either the client using a web page or developer of that web page is another thing to consider as well. In the case of the former, a developer must realize that untrusted clients could potentially be under control of an attacker while they must also realize that using popular packages such as npm and Bower in parallel with JS means to place faith in those systems to be secure.
User error can also come into play with regards to Browser and plugin coding errors which can allow vulnerabilities such as buffer overflows. What this means is that the input of some field was larger than suspected and had some of its memory overwrite an adjacent space in memory with its data. As a result, the data there could be lost and if it was something of great importance, an attacker could easily take advantage of this.