Scope

5/42
Recursos
Transcripción

El Scope o ámbito es lo que define el tiempo de vida de una variable, en que partes de nuestro código pueden ser usadas.

Global Scope

Variables disponibles de forma global se usa la palabra var, son accesibles por todos los scripts que se cargan en la página y se declaran fuera de una función o bloque. Aquí hay mucho riesgo de sobreescritura.

Function Scope

Variables declaradas dentro de una función utilizando var sólo visibles dentro de ella misma (incluyendo los argumentos que se pasan a la función).

Block Scope

Variables definidas dentro de un bloque, por ejemplo variables declaradas dentro un loop while o for. Se usa let y const para declarar este tipo de variables.

Module Scope

Cuando se denota un script de tipo module con el atributo type="module las variables son limitadas al archivo en el que están declaradas.

Aportes 196

Preguntas 44

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Apuntes que te ayudaran en tu vida en JS

Apuntes de esta clase:

Probablemente los 11 minutos y 50 segundos mas importantes de la clave para empezar a entender JS de manera profesional, durante meses… que digo años, he usado node, angular y otras librerías, y ahora POR FIN!! entiendo como funciona realmente todo el sistema de módulos, quizás se deba a que el scope module es reciente pero esta clase creo que es fundamental. Gracias profe por explicarlo tan claramente!!!

Scope

Scope o ámbito de una variable representa el tiempo de vida en el que esta existe, puede ser una variable que hayamos definido o el argumento a un función. Eso es muy importante por que evite que reescribamos el valor de una variable que ya habíamos definido. Por desgracia JavaScript no siempre tuve el mejor sistema de scope de variables, en el libro JavaScript: The Good Parts de Douglas Crockford se dice que el scope y variables globales son de las cosas más horrible que tiene el lenguaje. Por suerte esto a mejorado muchísimo, ahora tenemos a let y const que nos ayuda a evitar estos problemas.

Scope global

Vamos a hacer algunas pruebas en el código para experimentar con estas variables.

Si declaramos un var de la siguiente forma lo estaríamos haciendo globalmente.

var message = "¡Hello, Platzi!";

Si vamos a la consola y escribimos windows.message no da el mensaje que guardamos en la consola. Windows es nuestro ámbito global.

Si agregamos una CDN externo como jQuery podremos acceder a ese código globalmente. El peligro está en cambiar alguna característica del CDN global que trajimos.

var message = "¡Hello, Platzi!";
var $ = function(message) {
    console.log("Say: " + message);
}

Si escribimos en la consola lo siguiente no dará el resultado…

$('Hola')

 //  Say: Hola

Vimos que cambiamos por completo el acceso a elementos de jQuery, pero también nos dimos cuanta de que el message no era: ¡Hello, Platzi! si no Hola, a esto se le llama: Scope definition.

Ahora hagamos otro ejemplo, una función que imprimirá números.

function printNumbers(params) {
          for (var i = 0; i < 10; i++) {
              setTimeout(() => {
                  console.log(i)
              }, 100);
          }
      }

printNumbers()

Crea un siclo de 10 número del 0 al 9 y va a tener un retraso de 100ms, pero si ejecutamos este código pasa algo extraño:

// (10) 10 

Se imprime 10 veces 10 y eso no es lo que queremos.

Esto pasa por function scope, algo pasa con la variables var, pasa que el lenguaje lo declara como variable global y cuando llega el turno de imprimir el valor de i resulta que ya tiene 10. Se soluciona llamando a una función en el ciclo que ejecute el setTimeOut.

function printNumbers(params) {
          for (var i = 0; i < 10; i++) {
              function eventuallyPrintNumbers(n) {
                  setTimeout(() => {
                  console.log(n)
              }, 100);
              }
              eventuallyPrintNumbers(i)
          }
      }

      printNumbers()

Haciéndolo así var conserva su valor real por cada ciclo. El valor i paso a un scope n totalmente nuevo.

Block scope

Con las nuevas actualizaciones tenemos acceso a una variable que trabaja en el bloque de ejecución, siempre recordando su valor.

function printNumbers(params) {
        for (let i = 0; i < 10; i++) {
          setTimeout(() => {
            console.log(i);
          }, 100);
        }
      }

      printNumbers();

Module scope

Es probable que lo hayamos usado en Node o en React usando herramientas como Babel. Lo que hace es que el scope de esa variable se limite al archivo donde está definido.

<script  type="module"  src="./assets/index.js"></script>

El type="module" declara que el archivo es un módulo. Esto no está en todos los navegadores pero sí en los más modernos. Ya no podemos acceder a las variables globales de este archivo desde la consola.

Importar y exportar

Podemos separar código que esté en un archivo js usando export e import.

En nuestro archivo ./assets/index.js separaremos el código que usar nuestro media player en otro archivo llamado MediaPlayer.

Nuestro archivo index.js tendrá:

import MediaPlayer from "./MediaPlayer.js";
const video = document.querySelector("video");
const button = document.querySelector("button");


const player = new MediaPlayer({ el: video });

button.onclick = () => player.play();

Y el archivo MediaPlayer.js:

function MediaPlayer(config) {
  this.media = config.el;
}

MediaPlayer.prototype.play = function() {
  // if(this.media.paused){
  //   this.media.play();
  // } else {
  //   this.media.pause()
  // }
  // o podemos usar lo siguiente:
  this.media.paused ? this.media.play() : this.media.pause();
};

export default MediaPlayer;

Si exportamos una variable del archivo importado, ejemplo: export const foo = "hi", entonces tendríamos que importarlo de la siguiente forma:

import  MediaPlayer, { foo } from  "./MediaPlayer.js";

Entre llaves.

El scope es el lugar de vida de una variable y nos evita sobrescribir el valor de esta. En JavaScript tenemos cuatro:

  1. Global scope.

  2. Function scope.

  3. Block scope.

  4. Module scope.

Scope es el tiempo de vida y uso de una variable.
Existen distintos tipos:
Globales: Disponible en todo el código, alto riesgo de sobre-escritura con el Var.
Function Scope: va dentro de una función. Var, puede sobre escribirse en esa función, hay que tener cuidado con esta.
Block Scope: Let y const, te ayudan a que solo sea útil en un bloque especifico.
Module Scope: Modulares se limita a su archivo y no sale de ahí.

Recuerda:

  • En la consola puedes leer las variables locales con la palabra window.nombre-de-la-variable.

un breve resumen ❤️

MediaPlayer podemos también escribirlo como una clase

class MediaPlayer {
  constructor(config) {
    this.media = config.el;
  }

  play() {
    this.media.play();
  }

  pause() {
    this.media.pause();
  }

  togglePlay() {
    if (this.media.paused) {
      this.play();
    } else {
      this.pause();
    }
  }
}

export default MediaPlayer;

Scope (contexto de ejecución)

El scope, ámbito o alcance es el contexto actual de ejecución, en el cual los valores y expresiones son “visibles” y pueden ser referenciados, si una variable u otra expresión no esta en el “contexto actual de ejecución” (current scope), entonces estas no están disponibles para su uso. Los scopes - alcances también pueden tener una jerarquía de manera que los scopes de menor jerarquía tienen accesos a los scopes de mayor jerarquía pero no a la inversa.

Una función sirve como una clausura - closure en JavaScript esto significa que una función crea un scope - contexto de ejecución, entonces no se puede acceder a variables definidas dentro de una función desde afuera de esa función, ni desde otras funciones, por ejemplo:

function saludar() {
	var mensaje  = `soy una variable declarada 
	dentro de la función saludar`
	/*la variable "mensaje" solo se puede 
	utilizar dentro en la función saludar*/   
	console.log("funcion interna");
	console.log(mensaje);//el mesaje se imprime sin problema
}
/*la variable "mensaje" esta definida en el scope de la funcion 
"saludar" como estamos afuera de ese scope si intentamos acceder
a esa variable desde afuera de su scope-cotexto de ejecución 
tendremos un error ya que fuera de su contexto no existe.*/
console.log(mensaje);

Un scope puede heredar sus variables y expresiones hacia sus hijos pero los hijos no pueden heredar su scope a los padres, ejemplo:

function  hello(){
var  message  =  'Hello' ;
function  morning() {
/*esta función hereda el scope de su función
padre "hello" entonces podemos acceder a todas
sus variables y expresiones en este caso a la
variable "message"*/
var  full_message  =  message  +  ' good morning'
console.log(full_message)
}

function  nite(){
//esta función también hereda el scope de "hello"
var full_message  =  message  +  ' good nite'
var  onlyNite  =  'var onliNite solo soy accesible desde la función nite'
console.log(onlyNite)
console.log(full_message)
}
morning()
nite()
/*por el contrario la función "hello" no puede heredar
el scope de las funciones "morning" o "nite"
entonces la siguiente line de código notificara
un error que la variable "onliNite" no existe en su scope*/
console.log(onlyNite)
}

Tipos de scope

  1. Global scope:
    Todas las variables y expresiones están definidas en el contexto de ejecución global y como ya mencione gracias a la herencia de scope estas variables y expresiones son accesibles desde cualquier función.
    nota: cuando utilizamos es scope global para definir variables estas pueden ser sobrescritas si no se tiene precaución.
  2. Function scope:
    Variables declaradas dentro de una función sólo visibles y accesibles dentro de ella misma (incluyendo los argumentos que se pasan a la función).
  3. Block scope
    Un bloque se utiliza comúnmente para controlar sentencias de flujo como son condicionales (if, switch), loops (for, while, do - while). Un bloque se delimita por corchetes { } su sintaxis es la siguiente:
{ sentencia_1; sentencia_2; ... sentencia_n; }

la palabra reservada var no tiene scope de bloque por tal razón podríamos tener errores, como el siguiente ejemplo:

var x = 1;
{
  var x = 2;
}
console.log(x); // resultado 2
/*Este obtiene el resultado 2 ya que la sentencia 
'var x' dentro del grupo block tiene el mismo alcance 
que la sentencia 'var x'*/

Como podemos observar en el ejemplo anterior hay un problema con var ya que no tiene scope de bloque es por eso que desde ES2015 se introdujo let y const los cuales nos permite tener un scope de bloque, esto quiere decir que las variables solo van a vivir dentro del bloque de código donde se crean, por ejemplo:

let x = 1;
const y = "hola"
{
  let x = 2;
  const y = "adios"
}
console.log(x); // logs 1
console.log(y); // logs hola
/*El scope 'x = 2, y = 'adios' es limitado solamente 
al bloque en el que está definido.*/
  1. Module Scope:
    Cuando se denota un script de tipo module con el atributo type="module" las variables son limitadas al archivo en el que están declaradas.

Si alguno de ustedes quiere tener las llaves {}, corchetes [] y paréntesis () con colores como los tiene el profesor, les recomiendo el plugin de visual studio code: Bracket Pair Colorizer 2. Te ayudará a identificarlos mejor.
DATO EXTRA: puedes configurar sus colores en los settings en formato json de visual studio code de esta manera:

Resultado:

les recomiendo ver un video de sacha lifs sobre la ‘pila de ejecucion’ en su canal “La cocina del codigo”

Ya siento que comienzo a entender mas al profe c:

¿Cómo trabaja el SetTimeout JS?

link de jquery

<script src="https://unpkg.com/[email protected]/dist/jquery.js"></script>

En este repo van a encontrar 33 conceptos de JS para entenderlo en profundidad https://github.com/leonardomso/33-js-concepts

Y yo que pensaba tener buenos conocimientos en javascript, este curso es mágico!!

Lo que pasa aquí se llama hoisting.

Se puede comprimir un poco usando IIFE

Mozilla Docs

function printNumbers() {
      for (var i = 0; i < 10; i++) {
        (function (n) {
          setTimeout(() => {
            console.log(n)
          }, 100)
        })(i);
      }
    }

Datos importantes respecto a module scope:

  1. Si quieres importar un módulo ‘default’, los llaves ‘{}’ no son necesarias:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Using_the_default_export

  1. Puedes utilizar las llaves ‘{}’ para los exports con nombre:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Using_named_exports

  1. Se pueden exportar funciones, variables var, let y const. También se pueden exportar clases.

MediaPlayer.js

'use strict'

function MediaPlayer(config) {
    this.media = config.el
} 

MediaPlayer.prototype.play = (video) => video.play()
MediaPlayer.prototype.pause = (video) => video.pause()
MediaPlayer.prototype.button = (video) => video.paused ? video.play() : video.pause()

export default MediaPlayer

Index.js

'use strict'
import MediaPlayer from './MediaPlayer.js'

const video = document.querySelector('video')
const button = document.querySelector('button')
const player = new MediaPlayer({el: video})

button.onclick = () => player.button(video)

Me encanta Javascript, pero me cuesta un poco seguir al profesor, a pesar de que estoy siguiendo la ruta recomendada por platzi. Pienso que el profe se está saltando pasos para explicar

Platzi tiene en su blog este artículo que habla de scopes en javascript y de las diferencias entre let, const y var desde el punto de vista del scope: https://platzi.com/blog/como-funciona-el-scope-en-javascript/

No entiendo.

Ja, con esta explicación de var y let arreglé un bug que tenia del curso de fundamentos de Javascript con el juego de Simón!

A esto se le llama hoisting https://developer.mozilla.org/es/docs/Glossary/Hoisting

chicos como estan? para los que tuvieron ese error de la foto, a mi me funciono esta solucion. En VS Code, debes instalar la extension "live Server"
Una vez instalado le dan click a Go Live, asi se les vera el proyecto, ya que no es un error del codigo, si no que de configuracion con los protocolos que usa chrome.
por lo menos a mi me funciono

Muy buena la clase, luego de 2 años de trabajar con JS entiendo el porqué de los modulos.

Ahora lo entiendo todo!!

Alcance Léxico
Otro punto a mencionar es el alcance léxico. El alcance léxico significa que el alcance secundario tiene acceso a las variables definidas en el alcance primario. Las funciones secundarias están vinculadas léxicamente al contexto de ejecución de sus padres.

function foo1(){
    var fruit1 = 'apple';        
    const fruit2 = 'banana';     
    let fruit3 = 'strawberry';
    function foo2(){
        console.log(fruit1);
        console.log(fruit2);
        console.log(fruit3);
    }
    foo2();
}

foo1();

No conocía el Module Scope, y primera vez que me funciona un modulo. Gran clase

Tema fundamental en JS.

Comparto link del libro
JavaScript: The Good Parts

http://shop.oreilly.com/product/9780596517748.do

Lo de export me ayudo un monton en un proyecto en el que trabajo donde tengo un monton de llamadas a scripts dentro de un html para que puedan hablarse entre ellos. Jajaja, gran clase!! 😄

Comprensión del concepto MODULE SCOPE en relación a la sintaxis import tan ampliamente utilizada, esta explicación es clave para comprender el sistema de módules en JS y probablemente en NodeJs

Tengo problemas con CORS

Access to script at ‘file:///Users/Platzi/profesional_JS/assets/index.js’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
index.html:24 GET file:///Users/Platzi/profesional_JS/assets/index.js net::ERR_FAILED

¿Qué hago?

les dejo el link del curso de Scope y clossures por si necesitan una explicación un poco mas pausada, tambien abarca el tema de la proxima clase Curso de Scope y clossures

Ámbito de las variables en JS:
-Global scope
-function scope
-block scope
-module scope

Uff buen conocimiento para aplicarlo cada vez use js.

global scope
function scope
block scope
module scope

¿Existe un caso de uso para var o ya quedo obsoleto?

Para profundizar mas en este tema y en el que sigue (closures) les recomiendo el Curso de closures y scope aqui en Platzi 😃

Siempre he tenido lío con lo del scope y ahora me ha quedado mucho más claro! Gracias!! 😃 👏🏻

vean una clase magistral completasobre lo que es el scope de JavaScript aquí en este link
https://www.youtube.com/watch?v=s-7C09ymzK8

Si desean ver una clase magistral completa sobre lo que es el scope de JavaScript, les recomiendo que vayan a a este tutorial

Los valores que no pueden cambiar en la programación se conocen como INMUTABLES , mientras que los valores que se pueden cambiar son MUTABLES .
Aunque los valores const no se pueden reasignar, son MUTABLES ya que es posible modificar las propiedades de los objetos declarados con const.

Aqui les dejo los archivos que utilizamos al principio de la clase en blanco para empezarlos a trabajar:

scope.html

<html>
  <head>
    <title>Scope</title>
  </head>

  <body>
    <a href="/ejercicios/">Go back</a>
    <p><em>Abre la consola</em></p>

    <script src="https://unpkg.com/[email protected]/dist/jquery.js"></script>

    <script>
      // Global Scope
      // Function Scope
      // Block Scope
      // Module Scope
    </script>
  </body>
</html>

index.html

<head>
  <html>
    <title>Curso Profesional de JavaScript: Ejercicios</title>
  </head>

  <body>
    <a href="/">Go back</a>
    <h1>Índice</h1>
    <ol>
      <li><a href="/ejercicios/scope.html">Scope</a></li>
    </ol>
  </body>
</html>

cual es la diferencia entre export default o export const

o

const myApp()=>{}
export default myApp;

Salí a hacer otros cursos de JS que me hacían falta pero ya volví

Los aportes de la comunidad son simplemente increíbles 😄

Observaciones sobre el tema Scope.

  • Entender como funciona el scope permite escribir código más seguro donde el usuario solo tiene acceso a las cosas que necesitan a la vez. Se podría ver esto como algo parecido a el principio de mínimo privilegio que se aplica en seguridad de la información.

  • Las funciones que leen variables globales y según el valor que estás tengan devuelve una repuesta de una manera u otra hace que dichas funciones se vuelvan impredecibles porque dependen de cosas externas. Como buena practica de programación se debe declarar las variables con el scope más reducido posible.

  • las variables globales van a estar en memoria durante toda la ejecución del programa mientras que las locales solo van a estar en memoria durante la ejecución de la función o bloque al que pertenecen, en programas grandes esto puede ser importante para el rendimiento.

  • Shadowing (hacer sombre a una variable) esto es que podemos sobreescribir el valor de una variable global sin darnos cuenta generando un error y/o comportamiento impredecible en el código. El shadowing pasa cuando una variable de scope inferior tienen el mismo nombre que otra en un scope superior.

  • No confundir contexto de ejecución con contexto. Cuando se habla de scope se hace referencia al contexto de ejecución o entorno.

No tenia ese type=“module” en el radar, va muy bien este curso

Algo a corregir que veo que se está repitiendo mucho en los comentarios es que el scope no es el tiempo de vida de una variable, solamente es el alcance que tiene ella.

si no hubiese visto la explicacion del scope dentro de un for en el curso de Curso basico de Javascript… no hubiese entendido nada.

Ayuda
Aún no me funciona, lo inicie con live-server y tampoco aquí les paso mi código.

<!DOCTYPE html>
<html>
  <head>
    <title>PlatziMediaPlayer.js</title>
    <link
      rel="stylesheet"
      href="https://necolas.github.io/normalize.css/8.0.1/normalize.css"
    />
    <link rel="stylesheet" href="./assets/index.css" />
  </head>

  <body>
    <header>
      <h1>PlatziMediaPlayer.js</h1>
      <p>An extensible media player.</p>
    </header>

    <main class="container">
      <video>
        <source src="./assets/BigBuckBunny.mp4" />
      </video>

      <button>Play/Pause</button>
    </main>

    
    <script type="module" src="./assets/index.js"></script>
  </body>
</html>
import MediaPlayer from "./MediaPlayer.js";

const video = document.querySelector("video");
const player = new MediaPlayer({ el: video });

const button = document.querySelector("button");
button.onclick = () => player.togglePLay();
function MediaPlayer(config){
    this.media = config.el;
  }
  
  MediaPlayer.prototype.play = function(){
    this.media.play();
  }
  
  MediaPlayer.prototype.pause = function(){
    this.media.pause();
  }
  
  const player = new MediaPlayer({ el: video });
  button.onclick = () => {
    (player.media.paused)
      ? player.play()
      : player.pause();
}

export default MediaPlayer;

El navegador me da este error
MediaPlayer.js:13 Uncaught ReferenceError: video is not defined
at MediaPlayer.js:13

**No me funciona
La consola me da el siguente error:

Access to script at ‘file:///Users/andresalejandroargoteballotti/Desktop/media-player/assets/index.js’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
index.js:1 Failed to load resource: net::ERR_FAILED

**

<!DOCTYPE html>
<html>
  <head>
    <title>PlatziMediaPlayer.js</title>
    <link
      rel="stylesheet"
      href="https://necolas.github.io/normalize.css/8.0.1/normalize.css"
    />
    <link rel="stylesheet" href="./assets/index.css" />
  </head>

  <body>
    <header>
      <h1>PlatziMediaPlayer.js</h1>
      <p>An extensible media player.</p>
    </header>

    <main class="container">
      <video class="movie">
        <source src="./assets/BigBuckBunny.mp4" />
      </video>

      <button id="playButton">Play/Pause</button>
    </main>

    <script type="module" src="assets/index.js"></script>
  </body>
</html>

import MediaPlayer from "./MediaPlayer";

const video = document.querySelector("video");
const player = new MediaPlayer({ el: video });

const button = document.querySelector("button");
button.onclick = () => player.togglePlay();
MediaPlayer.prototype.play = function(){
    this.media.play();
}

MediaPlayer.prototype.pause = function(){
    this.media.pause();
}

MediaPlayer.prototype.togglePlay = function(){
    if(this.media.paused){
        this.play();
    }else{
        this.pause();
    }
}

export default MediaPlayer;

El Scope es el alcance de una variable, donde se usa y como se usa en el script.

Global Scope
Variables disponibles de forma global se usa la palabra var, son accesibles por todos los scripts que se cargan en la página. Aquí hay mucho riesgo de sobreescritura.

El Scope o ámbito es lo que define el tiempo de vida de una variable, en que partes de nuestro código pueden ser usadas.

Scope

Una de las cosas que tenemos que tener en cuenta al momento de declarar una función, es pensar quienes o que debe de tener acceso a las variables que estamos ocupando, es por seguridad y buenas prácticas

Excelente explicación!

Nunk pense comentar esto, pero tubo genial!!!

Recordé la clase de Scope con Oscar Barajas

Entiendo:

  • El import
  • El export
    ¿Por que debemos usar script type="module"?

Excelente curso, me ayudo a entender mucho de porque me costaba entender el alcance de JS en sus inicios

Por acá dejo mi código:
MediaPlayer.js

function MediaPlayer(config) {
    this.media = config.element;

    MediaPlayer.prototype.play_pause = function () {
        console.log(this.media.paused);
        this.media.paused ? this.media.play() : this.media.pause();
    }
}

export default MediaPlayer;

index.js

import MediaPlayer from "./MediaPlayer.js";

const video = document.querySelector("video");
const button = document.querySelector("button");

const player = new MediaPlayer({ element: video });
button.onclick = () => {
    player.play_pause();
}

el alcance de las variables y funciones en javascript es todo un tema pero el profe lo explica muy bien.

![](

  • [email protected] al momento de ejecutar me aparece este error, me dice algo relacionado con el uso del play que deberia usar load en vez de ello, alguien sabe como seria la sintaxis en ese
    caso??

el index.html que e encuentra dentro de ejercicios (0:59)

<html>
  <head>
    <title>Curso Profesional de JavaScript: Ejercicios</title>
  </head>

  <body>
    <a href="/">Go back</a>
    <h1>Índice</h1>
    <ol>
      <li><a href="/ejercicios/scope.html">Scope</a></li>
      <!-- <li><a href="/ejercicios/closures.html">Closures</a></li>
      <li>
        <a href="/ejercicios/this.html"><code>this</code></a>
      </li>
      <li>
        <a href="/ejercicios/call-apply-bind.html">
          <code>Function.prototype.call</code>,
          <code>Function.prototype.apply</code> y
          <code>Function.prototype.bind</code>
        </a>
      </li>
      <li><a href="/ejercicios/prototype.html">Prototype</a></li>
      <li>
        <a href="/ejercicios/prototypal-inheritance.html">
          Herencia Prototipal
        </a>
      </li>
      <li>
        <a href="/ejercicios/promises.html">Promesas</a>
      </li>
      <li>
        <a href="/ejercicios/proxy.html">Proxy</a>
      </li>
      <li>
        <a href="/ejercicios/generators.html">Generators</a>
      </li>
      <li>
        <a href="/ejercicios/abort-fetch.html">Abort Fetch</a>
      </li>
      <li>
        <a href="/ejercicios/typescript/index.html">TypeScript</a>
      </li>
      <li>
        <a href="/ejercicios/singleton/index.html">Singleton</a>
      </li>
      <li>
        <a href="/ejercicios/observer/index.html">Observer</a>
      </li>
      <li>
        <a href="/ejercicios/decorator/index.html">Decorator</a>
      </li> -->
    </ol>
  </body>
</html>

para los que no entienden, les recomiendo que revisen la ruta completa de frontend y van a entender mejor el scope.

PD: cambiando el var por el let en el for también bota el resultado buscado

function printNumbers() {
        for (let i = 0; i < 10; i++) {
            setTimeout(function() {
              console.log(i);
            }, 100);
        }
      }

      printNumbers();

Al momento de dar play o pause en el vídeo no me realiza ninguna acción… Este es mi código, Ayuda!!!

Conceptos aprendidos:

  • Es el ámbito o alcance de una variable.
  • Representa el tiempo de vida en el que una existe.
  • Define donde estarán disponibles, el acceso a ellas.
  • Puede ser una variable definida o el argumento de una función.
  • Evitamos re escribir el valor de una variable ya definido.
  • JavaScript no siempre tuve el mejor sistemas de variables.(libro JavaScript: The Good Parts de Douglas Crockford)
  • Esto cambio con la llegada de let y const.

Scope global

  • Si declaramos una variable fuera de una función o bloque tendrá scope global.
  • Son accesibles por todos los scripts cargados en la página.
  • Window es nuestro ámbito global.
  • Mucho riesgo de sobre escritura.

Scope function

  • Si declaramos la variable dentro de una función tendrá este scope.
  • Solo son accesibles dentro de la misma función (incluido los argumentos).
  • El ámbito lexical permite hacer la búsqueda del valor de una variable desde el ámbito de ejecución hacia el ámbito exterior.

Block scope

  • Una variable definida con const o let dentro de un bloque tendrá este scope.
  • Solo serán accesibles desde dicho bloque ( ejemplo dentro de un for, while, etc).

Module scope

  • Una variable definida en un archivo js cuyo script es denotado con el atributo type = module tendrá este scope. El type=“module” declara que el archivo es un módulo.
  • El ámbito de la variable será el módulo, las variables son limitadas al archivo en el que están declaradas.
  • Esto no está en todos los navegadores pero sí en los más modernos.

Codigo de nuestra App:
index.js

import MediaPlayer from './MediaPlayer.js'

const video = document.querySelector('video');
const button = document.querySelector('button');

const player = new MediaPlayer({el:video});

button.onclick = ()=> player.togglePlay();


MediaPlayer.js

function MediaPlayer(config) {
    this.media = config.el;
}

MediaPlayer.prototype.play = function () {
    this.media.play()
}

MediaPlayer.prototype.pause = function() {
    this.media.pause();
};

MediaPlayer.prototype.togglePlay = function () {
    this.media.paused?this.play():this.pause();
}
export default MediaPlayer

MediaPlayer.js con clase

class MediaPlayer{
  constructor(config){
    this.media = config.el
  }

  play(){
    this.media.play()
  }
  pause(){
    this.media.pause();
  }
  togglePlay(){
    this.media.paused?this.play():this.pause();
  }
}

aqui es donde pasa el script a module

Creé este gráfico para poder entender mejor el ejemplo que nos da Richard para entender scopes.
En la izquierda está representado el código donde todo el código nos devuelve 0, y en la derecha, el ejemplo que si funciona y nos devuelve los números del 0 al 9.

Aporte

Scope de las variables

  • Global = cuando la variable se declara de manera global y puede ser leída fuera de su bloque de código. aplica para variable var.

  • Local = cuando la variable let o cons se declaran en un a función y solo pueden ser accedidas desde este.

  • block = cuando se declara una variable en un bloque de código y solo funciona en ese bloque, como una variable let en un ciclo for.

  • Module=
    El ámbito de esta variable va a estar limitado al archivo donde fue definido. Ejemplos de uso regulares = node, react, babel.

Conclusiones de esta clase: No usar jamás var

muy educativa la clase, respect

Hola comunidad, si quedaron con ganas de conocer mas acerca del Scope o simplemete no entendieron mucho, les comparto un video que profundiza mas a detalle sobre el tema, pues esta claro que es algo sumamente importante y que lastimasoamente no se explica de una manera clara. La Cocina del Código - EL SCOPE en JAVASCRIPT

Recomiendo hacer el curso de V8 Engine de JS antes de iniciar este curso, con eso será mas sencillo entender la temática.

5. Scope

El Scope o ámbito es lo que define el tiempo de vida de una variable, en que partes de nuestro código pueden ser usadas.

Global Scope

Variables disponibles de forma global se usa la palabra var, son accesibles por todos los scripts que se cargan en la página y se declaran fuera de una función o bloque. Aquí hay mucho riesgo de sobrescritura. En ámbito global es toda variable que se declare fuera de una función o fuera de un bloque de código, pertenece al scope global. en el caso del navegador el scope global es windows.

<html>
<head>
    <title>Scope</title>
</head>

<body>
    <a href="/codigo-practico-ejercicios/">Go back</a>
    <p><em>Abre la consola</em></p>
    <script src="https://unpkg.com/[email protected]/dist/jquery.js"></script>

    <script>
        ///////////////////////////////////////////////
        // 				==Scope Global==
        ///////////////////////////////////////////////
        // en el navegador es representado por windows
        var message = 'Hello, Platzi!';

        // incluso cuando importamos librerías como jquery, estás
        // estarán disponibles en el ambito global, el peligro del,
        // scope global es que un script puede sobreescribir
        // el comportamiento de $ , diciendo  que al usar $ muestre un mensaje
        // si se escribi $ entonces
        var $ = function (message) {
            console.log('Say: ' + message);
        };
    </script>
</body>
</html>

Function Scope

Variables declaradas dentro de una función utilizando var solo visibles dentro de ella misma (incluyendo los argumentos que se pasan a la función). Pero en JavaScript esto tiene ciertas repercusiones cuando utilizamos la palabra var dentro de una función y es que estas

Cuando se declaran variables dentro de una función estas pertenecen a un entorno local sin embargo tanto variable declarado con var y funciones con function sufren de Hoisting, esto significa que javascript procesa de primero estás declaraciones de primero no importa en que lugar estén, estas son procesadas primero+

<html>
<head>
    <title>Scope</title>
</head>
<body>
    <a href="/codigo-practico-ejercicios/">Go back</a>
    <p><em>Abre la consola</em></p>
    <script>
        ///////////////////////////////////////////////
        // 				==Scope Function==
        ///////////////////////////////////////////////
		// En este ejemplo  el valor de i será 5 solamente en vez de 1,2,3,4,5
		// esto se debe a que el loop termina antes de que setTimeout llama
		// a la función esto se debe que i está en un mismo contexto y solo
		// se mostrará su resultado

		//    Existen dos posibles soluciones al problema:
		// 1. Se cambia la declaración de la variable "var i" por "let i"
		// 2. Utilizar el function Scope, es declaramos una nueva función
		//    que reciba por parámetro un valor "n"  que será i  y lo imprima
		//    en este caso, i está cambiando de scope y será recordado su valor
		//    en cada llamada

        function printNumbers1() {
            for (var i = 0; i < 5; i++) {
                setTimeout(function () {
                    console.log(i);
                }, 100);
            }
        }
	    
	    // solcuión 2 
        function printNumbers2() {
            for (var i = 0; i < 10; i++) {
                function eventuallyPrintNumber(n) {
                    setTimeout(function () {
                        console.log(n);
                    }, 100);
                }

                eventuallyPrintNumber(i);
            }
        }

        printNumbers1();
        printNumbers2();
    </script>
</body>
</html>

Block Scope

Variables definidas dentro de un bloque, por ejemplo variables declaradas dentro un loop while o for. Se usa let y const para declarar este tipo de variables.

<html>
<head>
    <title>Scope</title>
</head>
<body>
    <a href="/codigo-practico-ejercicios/">Go back</a>
    <p><em>Abre la consola</em></p>
    asasda
    <script>
        ///////////////////////////////////////////////
        // 				==Scope Block==
        ///////////////////////////////////////////////

        // Como se comentó anteriormen una solución al problema de
        // var i era cambiar la declaración por let i. Este pequeño
        //cambio hace la diferencia ya que let trabaja con el block scope
        // y esto quiere decir que por cada iteración del loop se está generan
        // un nuevo block scope permitiendo recordar el valor de i
        function printNumbers3() {
            for (let i = 0; i < 10; i++) {
                setTimeout(function () {
                    console.log(i);
                }, 100);
            }
        }

        printNumbers3();
    </script>
</body>
</html>

Module Scope

Cuando se denota un script de tipo module con el atributo type="module las variables son limitadas al archivo en el que están declaradas.

Esta sentencia va a declarar que el archivo es un módulo, esto no está disponible en todos los navegadores, pero si en los navegadores recientes, él al hacer esto está limitando el alcance del archivo. Para que nuestro DOM pueda importar módulos le añadimos el atributo type="module"

<script type="module" src="/folder/file-location"> </script>

Desde JavaScript se puede archivos los cuales se pueden exportar. Ejemplo: Se tiene un archivo Js llamado MediaPlayer.js y tiene lógica programada para controlar la reproducción de videos en el browser y se desea exportar está lógica para que otro archivo llamado index.js la pueda importar. Esto se haría de la siguiente:

archivo MediaPlayer.js

//
// Existencia hipotetica de 
// código lógico escrito ...
//
export default MediaPlayer;

//caso que se dese exportar una constante
//export const final_minute = '1:33';

archivo index.js

//
// Existencia hipotetica de 
// código lógico escrito ...
//
import MediaPlayer from  './MediaPlayer.js';

// caso que se dese importa 
//import MediaPlayer, { final_minute } from  './MediaPlayer.js';

Objetiva y clara clase

Scope: El scope puede definirse como el alcance que una variable tendrá en tu código, hay varios tipos de scopes, los cuales son:

  • Global Scope (Ambito Global):
    Toda variable que declaramos fuera de una funciónfunction(){}o un bloque
    {} se declara en el ambito global en inglés scope que es conocido como Window en JavaScript.

  • Function Scope (Ambito de Función): La variable es accesible solamente adentro de la funcion, pero afuera de ella no es accesible.

  • Module Scope (Ambito de modulo): La variable se procesa solo en el archivo o modulo y limita el alcance global.

el var es como si fuera un globo con helio se sale de su línea de código y se sube, esta es la referencia que yo uso para tenerlo siempre presente

Yo no sabia eso del module scope, pero si tu usas mas de un archivo js y linkeas todos estos a tu atchivo html, entonces podrás usar cualquier variable de manera indistinta en cualquiera de tus archivos js, aunque el orden en el que fueron llamados tiene mucha relevancia, se recomienda que primero vaya el archivo de los globales.

Por ejemplo, tu html queda asi

<html>
  <head></head>

  <body>
    @code

    <script src="./globals.js"></script>
    <script src="./first.js"></script>
    <script src="./second.js"></script>
  </body>
</html> 

En los archivos de first.js y second.js puedes usar cualquiera de las variables en globals.js

index.js

import MediaPlayer from "./MediaPlayer.js";

const video = document.querySelector("video");
const button = document.querySelector("button");

const player = new MediaPlayer({el: video});

button.onclick = () => {
    player.togglePlay();
}

MediaPlayer.js

class MediaPlayer {
    constructor(config) {
        this.media = config.el;
    }

    play() {
        this.media.play();
    }

    pause() {
        this.media.pause();
    }

    togglePlay() {
        if(this.media.paused) {
            this.play()
        }else{
            this.pause();
        }
    }
}
export default MediaPlayer;
4 tipos de Scope: - Global Scope, funciona en todas partes - Block Scope, funciona en un bloque AKA {} - Module Scope, funciona en un archivo, osea que en devtools no funcionara - Function Scope, dentro de una funcion

esta muy importante a definición del scope de una variable dentro de la ejecución del código JavaScript… es bastante complejo comienza sencillo con el scope global de var, luego entra let con el scope de bloque, y luego el scope module que ya esto es mas complejo estas variables tienen un alcance limitado al archivo en el que estan declaradas, y en este caso toca importar las declaraciones a donde se nesecitan con herramientas de ( import y export default ) o puede ser con (import const foonombre y export const foonombre)

Cual esla diferencia ente crear “Clases” de estas dos formas?
En qué caso debería utilizar una o la otra?

Forma 1

class MediaPlayer {
  constructor(config) {
    this.media = config.element;
  }

  play() {
    this.media.play();
  }

  pause() {
    this.media.pause();
  }
}

Forma 2 (así lo venimos haciendo en el curso)

function MediaPlayer(config) {
  this.media = config.element;
}

MediaPlayer.prototype.play = function () {
  this.media.play();
};

MediaPlayer.prototype.pause = function () {
  this.media.pause();
};

Excelente clase, Richard es muy bueno en JS.

me molesta lo rapido que va, tendria que ser un poco mas lento!!!

Les dejo mis apuntes de JavaScript y todas su actualizaciones para que se hagan un repaso y entiendan todo a la perfección.

[] (https://github.com/castellanosfelipe/Class-Javascript).

Si les fue de ayuda, dejenme una extrella.

El scope es el tiempo de vida de un avariable, los cuatro tipos de scope en JavaScript

Representa el tiempo de vida donde una variable o un argumento de una funcion existe. Esto es importante en la programacion ya que evita que re-escribamos variables o valores ya definidos. JS No siempre tuvo un mejor sistema de Scope pero este se a actualizado. Hoy existen Let & Const que nos ayudan a resolver problemas comunes.

  • Global Scope

Cuando creamos una variable fuera de una funcion o fuera de un bloque, esta queda en el scope global. Todos pueden acceder a ella y manipularla.

  • Function Scope

Variables declaradas dentro de una función sólo visibles y accesibles dentro de ella misma (incluyendo los argumentos que se pasan a la función) (De Juan Carlos Garcia Esquivel). Let trabaja sobre el block scope.

  • Module Scope

La vida de una variable estara limitado al archivo donde esta definido. Si al momento de llamar nuestro archivo JS en HTML agregamos el atributo type=‘module’ Esto provocara que las variables no puedan ser llamadas fuera del archivo o modulo. Si nosotros exportamos de otro archivo pues ahora podemos llamar las variables de sus archivos y compartimos el modulo.

En JS tenemos 4 scopes: global, function, block y module.

Hola,

Me ayudan por favor con este error:
index.html:1 Access to script at ‘file:///E:/Platzi/Profesional%20de%20javascript/assets/index.js’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
index.html:25 GET file:///E:/Platzi/Profesional%20de%20javascript/assets/index.js net::ERR_FAILED

<html>
  <head>
    <title>PlatziMediaPlayer.js</title>
    <link
      rel="stylesheet"
      href="https://necolas.github.io/normalize.css/8.0.1/normalize.css"
    />
    <link rel="stylesheet" href="./assets/index.css" />
  </head>

  <body>
    <header>
      <h1>PlatziMediaPlayer.js</h1>
      <p>An extensible media player.</p>
    </header>

    <main class="container">
      <video class="movie">
        <source src="./assets/BigBuckBunny.mp4" />
      </video>

      <button>Play/Pause</button>
    </main>

    <script type="module" src="./assets/index.js"></script>
  </body>
</html>
import MediaPlayer from'./MediaPlayer.js';

const video = document.querySelector('video');
const player = new MediaPlayer({ el: video });

const button = document.querySelector('button');
button.onclick = () => player.togglePlay();


function MediaPlayer(config) {
  this.media = config.el;
}

MediaPlayer.prototype.play = function() {
  this.media.play();
};

MediaPlayer.prototype.pause = function() {
  this.media.pause();
};

MediaPlayer.prototype.togglePlay = function() {
  if (this.media.paused) {
    this.play();
  } else {
    this.pause();
  }
};

export default MediaPlayer;

Función setTimeout()

Conclusiones