ECMAScript 6, también conocido como ECMAScript 2015, es la última versión del estándar ECMAScript. ES6 es una actualización importante del lenguaje y la primera actualización del lenguaje desde que se estandarizó ES5 en 2009. La implementación de estas características en los principales motores de JavaScript ya está en marcha.
Consulte el estándar ES6 para conocer las especificaciones completas del lenguaje ECMAScript 6.
ES6 incluye las siguientes características nuevas:
Las flechas son una abreviatura de funciones que utilizan la sintaxis =>
. Son sintácticamente similares a la característica relacionada en C#, Java 8 y CoffeeScript. Admiten tanto cuerpos de bloques de instrucciones como cuerpos de expresiones que devuelven el valor de la expresión. A diferencia de las funciones, las flechas comparten el mismo léxico this
que el código que las rodea.
// Expression bodies
var odds = evens . map ( v => v + 1 ) ;
var nums = evens . map ( ( v , i ) => v + i ) ;
var pairs = evens . map ( v => ( { even : v , odd : v + 1 } ) ) ;
// Statement bodies
nums . forEach ( v => {
if ( v % 5 === 0 )
fives . push ( v ) ;
} ) ;
// Lexical this
var bob = {
_name : "Bob" ,
_friends : [ ] ,
printFriends ( ) {
this . _friends . forEach ( f =>
console . log ( this . _name + " knows " + f ) ) ;
}
}
Más información: Funciones de flecha de MDN
Las clases de ES6 son un azúcar simple sobre el patrón OO basado en prototipos. Tener una forma declarativa única y conveniente hace que los patrones de clase sean más fáciles de usar y fomenta la interoperabilidad. Las clases admiten herencia basada en prototipos, superllamadas, instancias y métodos y constructores estáticos.
class SkinnedMesh extends THREE . Mesh {
constructor ( geometry , materials ) {
super ( geometry , materials ) ;
this . idMatrix = SkinnedMesh . defaultMatrix ( ) ;
this . bones = [ ] ;
this . boneMatrices = [ ] ;
//...
}
update ( camera ) {
//...
super . update ( ) ;
}
get boneCount ( ) {
return this . bones . length ;
}
set matrixType ( matrixType ) {
this . idMatrix = SkinnedMesh [ matrixType ] ( ) ;
}
static defaultMatrix ( ) {
return new THREE . Matrix4 ( ) ;
}
}
Más información: Clases MDN
Los literales de objetos se amplían para admitir la configuración del prototipo en la construcción, abreviatura de foo: foo
, definición de métodos, realización de superllamadas y cálculo de nombres de propiedades con expresiones. Juntos, estos también acercan los literales de objetos y las declaraciones de clases, y permiten que el diseño basado en objetos se beneficie de algunas de las mismas comodidades.
var obj = {
// __proto__
__proto__ : theProtoObj ,
// Shorthand for ‘handler: handler’
handler ,
// Methods
toString ( ) {
// Super calls
return "d " + super . toString ( ) ;
} ,
// Computed (dynamic) property names
[ 'prop_' + ( ( ) => 42 ) ( ) ] : 42
} ;
Más información: MDN Gramática y tipos: Literales de objetos
Las cadenas de plantilla proporcionan azúcar sintáctico para construir cadenas. Esto es similar a las funciones de interpolación de cadenas en Perl, Python y más. Opcionalmente, se puede agregar una etiqueta para permitir personalizar la construcción de la cadena, evitando ataques de inyección o construyendo estructuras de datos de nivel superior a partir del contenido de la cadena.
// Basic literal string creation
`In JavaScript 'n' is a line-feed.`
// Multiline strings
`In JavaScript this is
not legal.`
// String interpolation
var name = "Bob" , time = "today" ;
`Hello ${ name } , how are you ${ time } ?`
// Construct an HTTP request prefix is used to interpret the replacements and construction
POST `http://foo.org/bar?a= ${ a } &b= ${ b }
Content-Type: application/json
X-Credentials: ${ credentials }
{ "foo": ${ foo } ,
"bar": ${ bar } }` ( myOnReadyStateChangeHandler ) ;
Más información: Cadenas de plantilla MDN
La desestructuración permite la vinculación mediante coincidencia de patrones, con soporte para hacer coincidir matrices y objetos. La desestructuración es suave, similar a la búsqueda de objetos estándar foo["bar"]
, y produce valores undefined
cuando no se encuentran.
// list matching
var [ a , , b ] = [ 1 , 2 , 3 ] ;
// object matching
var { op : a , lhs : { op : b } , rhs : c }
= getASTNode ( )
// object matching shorthand
// binds `op`, `lhs` and `rhs` in scope
var { op , lhs , rhs } = getASTNode ( )
// Can be used in parameter position
function g ( { name : x } ) {
console . log ( x ) ;
}
g ( { name : 5 } )
// Fail-soft destructuring
var [ a ] = [ ] ;
a === undefined ;
// Fail-soft destructuring with defaults
var [ a = 1 ] = [ ] ;
a === 1 ;
Más información: Tarea de desestructuración de MDN
Valores de parámetros predeterminados evaluados por el destinatario. Convierta una matriz en argumentos consecutivos en una llamada a función. Vincula los parámetros finales a una matriz. Rest reemplaza la necesidad de arguments
y aborda casos comunes de manera más directa.
function f ( x , y = 12 ) {
// y is 12 if not passed (or passed as undefined)
return x + y ;
}
f ( 3 ) == 15
function f ( x , ... y ) {
// y is an Array
return x * y . length ;
}
f ( 3 , "hello" , true ) == 6
function f ( x , y , z ) {
return x + y + z ;
}
// Pass each elem of array as argument
f ( ... [ 1 , 2 , 3 ] ) == 6
Más información de MDN: Parámetros predeterminados, Parámetros de descanso, Operador de extensión
Construcciones de enlace con ámbito de bloque. let
es la nueva var
. const
es de asignación única. Las restricciones estáticas impiden su uso antes de la asignación.
function f ( ) {
{
let x ;
{
// okay, block scoped name
const x = "sneaky" ;
// error, const
x = "foo" ;
}
// error, already declared in block
let x = "inner" ;
}
}
Más información de MDN: declaración let, declaración const
Los objetos iteradores permiten iteraciones personalizadas como CLR IEnumerable o Java Iterable. Generalice for..in
a una iteración personalizada basada en iteradores con for..of
. No es necesario realizar una matriz, lo que permite patrones de diseño perezosos como LINQ.
let fibonacci = {
[ Symbol . iterator ] ( ) {
let pre = 0 , cur = 1 ;
return {
next ( ) {
[ pre , cur ] = [ cur , pre + cur ] ;
return { done : false , value : cur }
}
}
}
}
for ( var n of fibonacci ) {
// truncate the sequence at 1000
if ( n > 1000 )
break ;
console . log ( n ) ;
}
La iteración se basa en estas interfaces tipo pato (usando la sintaxis de tipo TypeScript solo para exposición):
interface IteratorResult {
done : boolean ;
value : any ;
}
interface Iterator {
next ( ) : IteratorResult ;
}
interface Iterable {
[ Symbol . iterator ] ( ) : Iterator
}
Más información: MDN para...de
Los generadores simplifican la creación de iteradores utilizando function*
y yield
. Una función declarada como función* devuelve una instancia de Generador. Los generadores son subtipos de iteradores que incluyen next
y throw
adicionales. Estos permiten que los valores regresen al generador, por lo que yield
es una forma de expresión que devuelve un valor (o arroja).
Nota: También se puede utilizar para habilitar la programación asíncrona tipo 'espera'; consulte también la propuesta await
de ES7.
var fibonacci = {
[ Symbol . iterator ] : function * ( ) {
var pre = 0 , cur = 1 ;
for ( ; ; ) {
var temp = pre ;
pre = cur ;
cur += temp ;
yield cur ;
}
}
}
for ( var n of fibonacci ) {
// truncate the sequence at 1000
if ( n > 1000 )
break ;
console . log ( n ) ;
}
La interfaz del generador es (usando la sintaxis de tipo TypeScript solo para exposición):
interface Generator extends Iterator {
next ( value ?: any ) : IteratorResult ;
throw ( exception : any ) ;
}
Más información: Protocolos de iteración MDN
Adiciones continuas para admitir Unicode completo, incluida una nueva forma literal Unicode en cadenas y un nuevo modo RegExp u
para manejar puntos de código, así como nuevas API para procesar cadenas en el nivel de puntos de código de 21 bits. Estas adiciones admiten la creación de aplicaciones globales en JavaScript.
// same as ES5.1
"?" . length == 2
// new RegExp behaviour, opt-in ‘u’
"?" . match ( / . / u ) [ 0 ] . length == 2
// new form
"u{20BB7}" == "?" == "uD842uDFB7"
// new String ops
"?" . codePointAt ( 0 ) == 0x20BB7
// for-of iterates code points
for ( var c of "?" ) {
console . log ( c ) ;
}
Más información: MDN RegExp.prototype.unicode
Soporte a nivel de lenguaje para módulos para la definición de componentes. Codifica patrones de cargadores de módulos JavaScript populares (AMD, CommonJS). Comportamiento en tiempo de ejecución definido por un cargador predeterminado definido por el host. Modelo implícitamente asíncrono: no se ejecuta ningún código hasta que los módulos solicitados estén disponibles y procesados.
// lib/math.js
export function sum ( x , y ) {
return x + y ;
}
export var pi = 3.141593 ;
// app.js
import * as math from "lib/math" ;
alert ( "2π = " + math . sum ( math . pi , math . pi ) ) ;
// otherApp.js
import { sum , pi } from "lib/math" ;
alert ( "2π = " + sum ( pi , pi ) ) ;
Algunas características adicionales incluyen export default
y export *
:
// lib/mathplusplus.js
export * from "lib/math" ;
export var e = 2.71828182846 ;
export default function ( x ) {
return Math . log ( x ) ;
}
// app.js
import ln , { pi , e } from "lib/mathplusplus" ;
alert ( "2π = " + ln ( e ) * pi * 2 ) ;
Más información de MDN: declaración de importación, declaración de exportación
Soporte de cargadores de módulos:
El cargador de módulos predeterminado se puede configurar y se pueden construir nuevos cargadores para evaluar y cargar código en contextos aislados o restringidos.
// Dynamic loading – ‘System’ is default loader
System . import ( 'lib/math' ) . then ( function ( m ) {
alert ( "2π = " + m . sum ( m . pi , m . pi ) ) ;
} ) ;
// Create execution sandboxes – new Loaders
var loader = new Loader ( {
global : fixup ( window ) // replace ‘console.log’
} ) ;
loader . eval ( "console.log('hello world!');" ) ;
// Directly manipulate module cache
System . get ( 'jquery' ) ;
System . set ( 'jquery' , Module ( { $ : $ } ) ) ; // WARNING: not yet finalized
Estructuras de datos eficientes para algoritmos comunes. WeakMaps proporciona tablas auxiliares con claves de objetos sin fugas.
// Sets
var s = new Set ( ) ;
s . add ( "hello" ) . add ( "goodbye" ) . add ( "hello" ) ;
s . size === 2 ;
s . has ( "hello" ) === true ;
// Maps
var m = new Map ( ) ;
m . set ( "hello" , 42 ) ;
m . set ( s , 34 ) ;
m . get ( s ) == 34 ;
// Weak Maps
var wm = new WeakMap ( ) ;
wm . set ( s , { extra : 42 } ) ;
wm . size === undefined
// Weak Sets
var ws = new WeakSet ( ) ;
ws . add ( { data : 42 } ) ;
// Because the added object has no other references, it will not be held in the set
Más información de MDN: Mapa, Conjunto, WeakMap, WeakSet
Los servidores proxy permiten la creación de objetos con toda la gama de comportamientos disponibles para alojar objetos. Puede usarse para interceptación, virtualización de objetos, registro/elaboración de perfiles, etc.
// Proxying a normal object
var target = { } ;
var handler = {
get : function ( receiver , name ) {
return `Hello, ${ name } !` ;
}
} ;
var p = new Proxy ( target , handler ) ;
p . world === 'Hello, world!' ;
// Proxying a function object
var target = function ( ) { return 'I am the target' ; } ;
var handler = {
apply : function ( receiver , ... args ) {
return 'I am the proxy' ;
}
} ;
var p = new Proxy ( target , handler ) ;
p ( ) === 'I am the proxy' ;
Hay trampas disponibles para todas las metaoperaciones a nivel de tiempo de ejecución:
var handler =
{
get :... ,
set :... ,
has :... ,
deleteProperty :... ,
apply :... ,
construct :... ,
getOwnPropertyDescriptor :... ,
defineProperty :... ,
getPrototypeOf :... ,
setPrototypeOf :... ,
enumerate :... ,
ownKeys :... ,
preventExtensions :... ,
isExtensible :...
}
Más información: Proxy MDN
Los símbolos permiten el control de acceso al estado del objeto. Los símbolos permiten que las propiedades se claven mediante una string
(como en ES5) o symbol
. Los símbolos son un nuevo tipo primitivo. Parámetro description
opcional utilizado en la depuración, pero no forma parte de la identidad. Los símbolos son únicos (como gensym), pero no privados, ya que se exponen mediante funciones de reflexión como Object.getOwnPropertySymbols
.
var MyClass = ( function ( ) {
// module scoped symbol
var key = Symbol ( "key" ) ;
function MyClass ( privateData ) {
this [ key ] = privateData ;
}
MyClass . prototype = {
doStuff : function ( ) {
... this [ key ] . . .
}
} ;
return MyClass ;
} ) ( ) ;
var c = new MyClass ( "hello" )
c [ "key" ] === undefined
Más información: Símbolo MDN
En ES6, las funciones integradas como Array
, Date
y DOM Element
se pueden subclasificar.
La construcción de objetos para una función denominada Ctor
ahora utiliza dos fases (ambas enviadas virtualmente):
Ctor[@@create]
para asignar el objeto, instalando cualquier comportamiento especial El conocido símbolo @@create
está disponible a través de Symbol.create
. Las funciones integradas ahora exponen su @@create
explícitamente.
// Pseudo-code of Array
class Array {
constructor ( ... args ) { /* ... */ }
static [ Symbol . create ] ( ) {
// Install special [[DefineOwnProperty]]
// to magically update 'length'
}
}
// User code of Array subclass
class MyArray extends Array {
constructor ( ... args ) { super ( ... args ) ; }
}
// Two-phase 'new':
// 1) Call @@create to allocate object
// 2) Invoke constructor on new instance
var arr = new MyArray ( ) ;
arr [ 1 ] = 12 ;
arr . length == 2
Muchas adiciones de bibliotecas nuevas, incluidas bibliotecas básicas de matemáticas, asistentes de conversión de matrices, asistentes de cadenas y Object.assign para copiar.