Post Top Ad

Your Ad Spot

domingo, 28 de junio de 2020

Característica ES: globalThis

La propuesta ECMAScript " globalThis" de Jordan Harband proporciona una nueva forma estándar de acceder al objeto global.

Alcance global de JavaScript   

Los ámbitos variables de JavaScript están anidados y forman un árbol cuya raíz es el ámbito global. Ese alcance es solo el alcance directo cuando un script se ejecuta en un navegador web. Hay dos tipos de variables globales:
  • Las variables declarativas globales son variables normales.
    • Se crean en el nivel superior de un script, a través de const`let y declaraciones de clase.
  • Las variables de objeto global se almacenan en propiedades del objeto global .
    • Se crean en el nivel superior de un script, a través de vardeclaraciones de funciones.
    • También se pueden crear, eliminar y leer a través del objeto global.
    • Aparte de eso, funcionan como variables normales.
Se puede acceder al objeto global a través de globalThisEl siguiente fragmento HTML muestra globalThisy los diferentes tipos de variables globales.
<script>
  const one = 1;
  var two = 2;
</script>
<script>
  // All scripts share the same top-level scope:
  console.log(one); // 1
  console.log(two); // 2
  
  // Not all declarations create properties of the global object:
  console.log(globalThis.one); // undefined
  console.log(globalThis.two); // 2
</script>
Tenga en cuenta que cada módulo tiene su propio alcance. Por lo tanto, las variables que existen en el nivel superior de un módulo no son globales. El siguiente diagrama ilustra cómo se relacionan los diversos ámbitos.

Valores de this  

Siempre que no haya receptor (el objeto de una llamada al método), el valor de thisdepende del alcance actual:
  • Nivel superior de scripts: objeto global (en los navegadores, hay una indirecta que exploraremos más adelante)
  • Nivel superior de los módulos ECMAScript: undefined
  • Durante una llamada de función:
    • Modo estricto (incluidos los módulos): undefined
    • Modo descuidado: igual que global this
Si llama eval()indirectamente, se ejecuta de forma global, descuidadamente. Por lo tanto, puede usar el siguiente código para obtener el global this:
const theGlobalThis = eval.call(undefined, 'this');
new Function() También se evalúa siempre en modo descuidado:
const theGlobalThis = new Function('return this')();
Hay una advertencia importante, sin embargo: evalnew Function(), etc, no están disponibles si se utiliza CSP (Política de Seguridad de Contenido). Eso hace que este enfoque sea inadecuado en muchos casos.

En los navegadores, el global thisno apunta directamente al objeto global   

Como ejemplo, considere un iframe en una página web:
  • Cada vez que srccambia el iframe, obtiene un nuevo objeto global.
  • Sin embargo, el global thissiempre tiene el mismo valor, que puede verificarse desde fuera del iframe, como se demuestra en la propuesta de función .
Los navegadores logran eso al distinguir dos objetos:
  • WindowEs el objeto global. Cambia cada vez que cambia la ubicación.
  • WindowProxyes un objeto que reenvía todos los accesos a la corriente WindowEste objeto nunca cambia.
En los navegadores, global se thisrefiere a WindowProxyen todas partes, se refiere directamente al objeto global.

globalThisy alternativas ( window, etc.)   

globalThisEs la nueva forma estándar de acceso global thisLas formas simples existentes dependen de la plataforma:
  • Variable global window: es la forma clásica de referirse al objeto global. Pero no funciona en Node.js y en Web Workers.
  • Variable global self: está disponible en Web Workers y navegadores en general. Pero no es compatible con Node.js. Algunas personas selfaparecen en el código, como una señal de que ese código funciona tanto en Web Workers como en la configuración normal del navegador.
  • Variable global global: solo está disponible en Node.js.
La propuesta también estandariza que el objeto global debe tener Object.prototypeen su cadena de prototipo. Lo siguiente ya es cierto en los navegadores web de hoy:
> Object.prototype.isPrototypeOf(window)
true

Casos de uso para globalThis  

El objeto global ahora se considera un error que JavaScript no puede eliminar, debido a la compatibilidad con versiones anteriores. Afecta negativamente el rendimiento y generalmente es confuso.
ECMAScript introdujo varias características que facilitan evitar el objeto global, por ejemplo:
  • constlety las declaraciones de clase no crean propiedades de objetos globales cuando se usan en el ámbito global.
  • Cada módulo ECMAScript tiene su propio alcance local.
Normalmente es preferible referirse a las variables globales como variables y no como propiedades de globalThisEso siempre ha funcionado en todas las plataformas JavaScript.
Por lo tanto, hay relativamente pocos casos de uso para globalThis, por ejemplo:
  • Polyfills y cuñas que proporcionan nuevas funciones en los motores de JavaScript.
  • Detección de características, para descubrir qué características admite un motor de JavaScript.

Un polyfill   

El autor de la propuesta, Jordan Harband, ha escrito un polyfill para globalThis.
Usándolo con la sintaxis de CommonJS:
// Computing the value of `global`
var global = require('globalthis')();

// Shimming `global` (installing it globally)
require('globalthis/shim')();
Utilizándolo con la sintaxis del módulo ES6:
// Computing the value of `global`
import getGlobal from 'globalthis';
const global = getGlobal();

// Shimming `global` (installing it globally)
import shim from ‘globalthis/shim’; shim();
El paquete siempre utiliza el enfoque "más nativo" disponible ( globalen Node.js, etc., windowen contextos normales de navegador, etc.).

Calcular una referencia al objeto global   

Internamente, el polyfill usa la función getPolyfill()para calcular una referencia al objeto global. Así es como se logra:
polyfill.js:
var implementation = require('./implementation');
module.exports = function getPolyfill() {
  if (typeof global !== 'object' || !global
    || global.Math !== Math || global.Array !== Array) {
    return implementation;
  }
  return global;
};
implementation.js:
if (typeof self !== 'undefined') {
  module.exports = self;
} else if (typeof window !== 'undefined') {
  module.exports = window;
} else if (typeof global !== 'undefined') {
  module.exports = global;
} else {
  module.exports = Function('return this')();
}

Preguntas frecuentes: globalThis  

¿Por qué no usar globalselfwindowen todas partes?  

Por desgracia, eso no es posible, porque muchas bibliotecas de JavaScript usan estas variables para detectar en qué plataforma se están ejecutando.

¿Qué otros nombres globalThisfueron considerados?  

Un problema en el repositorio de la propuesta enumera los nombres que se consideraron y por qué fueron rechazados.

Fuentes y antecedentes   

Antecedentes generales:
  • Una visión general de las variables globales: sección "Variables globales" en "JavaScript para programadores impacientes"
  • Información detallada sobre cómo JavaScript gestiona sus variables globales: "¿Cómo funcionan realmente las variables globales de JavaScript?" en 2ality
  • Antecedentes útiles de lo que sucede en los navegadores: "Definición de los objetos WindowProxy, Window y Location" por Anne van Kesteren
  • Varias formas de acceder al thisvalor global "Un horroroso globalThispolyfill en JavaScript universal" por Mathias Bynens
Especificaciones:
  • Muy técnico: "Reinos, objetos de configuración y objetos globales" en el estándar HTML WHATWG
  • En la especificación ECMAScript, puede ver cómo los navegadores web personalizan global this"InitializeHostDefinedRealm ()"

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

outbrain

Páginas