Rumah >hujung hadapan web >Soal Jawab bahagian hadapan >Adakah pembolehubah dibalut dalam es6 jika dikira sebagai di dalam blok?

Adakah pembolehubah dibalut dalam es6 jika dikira sebagai di dalam blok?

青灯夜游
青灯夜游asal
2022-11-21 16:21:581432semak imbas

es6 dalam blok pengiraan berubah yang dibalut dengan if. Terdapat skop peringkat blok baharu dalam es6 Kod yang dibalut oleh "{ }" ialah skop peringkat blok "{}", jika penyataan, dan kod dalam gelung for dalam fungsi semuanya tergolong dalam blok-; skop tahap dan dikira dalam blok. Dalam ES6, skop peringkat blok dibenarkan untuk bersarang sewenang-wenangnya Skop luar tidak boleh membaca pembolehubah skop dalam boleh menentukan pembolehubah dengan nama skop luar yang sama.

Adakah pembolehubah dibalut dalam es6 jika dikira sebagai di dalam blok?

Persekitaran pengendalian tutorial ini: sistem Windows 7, ECMAScript versi 6, komputer Dell G3.

Apakah itu skop peringkat blok? Skop blok dibalut dengan , dan

pernyataan dan

di dalam ES6 pernyataan juga tergolong dalam skop blok. { }if{}, pernyataan if dan untuk gelung dalam fungsi juga tergolong dalam skop peringkat blok Pembolehubah yang ditakrifkan oleh let dan const hanya boleh sah dalam skop. for{ }

Mengapa skop peringkat blok diperlukan

Senario pertama: pembolehubah dalaman akan menimpa pembolehubah luaran

Senario kedua: Pembolehubah gelung yang digunakan untuk mengira kebocoran ke dalam pembolehubah global

var time = new Date()
function fx () {
    console.log(time) // undefined
    if (false) {
        var time = 'hello'
    }
}
fx()
{
    var a = 1
    console.log(a) // 1
}
console.log(a) // 1
// 通过var定义的变量可以跨块作用域访问到。
Pembolehubah yang ditakrifkan dengan

dalam gelung boleh diakses dalam skop luaran

for dalam pernyataan 🎜>var boleh diakses dalam skop luaran Perbezaan antara

for (var i = 0; i < 3; i++) {

}

for (let j = 0; j < 3; j++) {

}
// 3
console.log(i);
// Uncaught ReferenceError: j is not defined
console.log(j);

if dan var ialah

<.>

akan dilaksanakan, jadi if(true) dicetak sebagai if (false)

    Pernyataan tugasan dalam
  • tidak akan dilaksanakan, tetapi pembolehubah yang diisytiharkan if(true) akan dinaikkan pangkat kerana promosi pembolehubah Dinaikkan pangkat ke peringkat teratas skop, jadi ia dicetak sebagai a3
  • if(false)var bundefinedSkop peringkat blok (ES6 menyediakan pembolehubah let & const untuk melaksanakan skop skop peringkat blok)
if (true) {
	var a = 3
}

if (false) {
	var b = 3
}
// 3
console.log(a);
// undefined
console.log(b);

if (true) {
	let c = 3
}
// Uncaught ReferenceError: c is not defined
console.log(c);

ES6 membenarkan sarang sewenang-wenangnya skop peringkat blok. Kod di atas menggunakan skop peringkat blok lima peringkat dan setiap tahap ialah skop yang berasingan. Skop peringkat keempat tidak boleh membaca pembolehubah dalaman skop peringkat kelima.

function fxFn () { // 这是一个块级作用域
    let fx = 'fx is a great girl'
    if (true) { // 这是一个块级作用域
        let fx = 'fx is 18 years old'
    }
    console.log(fx) // fx is a great girl
}
fxFn()
 
// 块级作用域之间相互不影响
Skop dalaman boleh menentukan pembolehubah dengan nama yang sama dalam skop luar.

{{{{
  {
    let fnn = 'Hello'
  }
  console.log(fnn); // 报错
}}}};

Kemunculan skop peringkat blok sebenarnya menjadikan ungkapan fungsi yang dilaksanakan segera tanpa nama yang digunakan secara meluas (tanpa nama

) tidak lagi diperlukan.
{{{{
  let fnn = 'Hello';
  {
    let fnn = 'Hello'
  }
}}}};

Skop peringkat blok dan pengisytiharan fungsiIIFE

// IIFE 写法
(function () {
  var tmp = '...';
  // ...
}());
 
// 块级作用域写法
{
  let tmp = '...';
  // ...
}

menetapkan bahawa fungsi hanya boleh berada dalam skop dan fungsi peringkat atas skop Diisytiharkan masuk, tidak boleh diisytiharkan dalam skop peringkat blok. Dua pengisytiharan fungsi di atas adalah menyalahi undang-undang mengikut peruntukan .

Walau bagaimanapun, penyemak imbas tidak mematuhi keperluan ini Untuk serasi dengan kod lama, mereka masih menyokong fungsi pengisytiharan dalam skop peringkat blok, jadi kedua-dua situasi di atas sebenarnya boleh dijalankan tanpa melaporkan ralat. ES5

// 情况一
if (true) {
  function f() {}
}
 
// 情况二
try {
  function f() {}
} catch(e) {
  // ...
}
memperkenalkan skop blok, secara eksplisit membenarkan fungsi diisytiharkan dalam skop blok.

menyatakan bahawa dalam skop peringkat blok, pernyataan pengisytiharan fungsi berkelakuan seperti ES5 dan tidak boleh dirujuk di luar skop peringkat blok.

Apabila kod di atas dijalankan dalam

, anda akan mendapat "ES6", kerana fungsi ES6 yang diisytiharkan dalam let akan dinaikkan pangkat ke kepala fungsi, dan kod larian sebenar seperti berikut.

function f() { console.log('I am outside!'); }
 
(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }
 
  f();
}());

ES5 secara teorinya, anda akan mendapat "I am inside!". Oleh kerana fungsi yang diisytiharkan dalam skop peringkat blok adalah serupa dengan if, ia tidak mempunyai kesan di luar skop. f Walau bagaimanapun, jika anda benar-benar menjalankan kod di atas dalam

penyemak imbas, ralat akan dilaporkan. Mengapa ini?
// ES5 环境
function f() { console.log('I am outside!'); }
 
(function () {
  function f() { console.log('I am inside!'); }
  if (false) {
  }
  f();
}());

ES6Kod di atas akan melaporkan ralat dalam penyemak imbas I am outside!. let
Ternyata jika peraturan pemprosesan untuk fungsi yang diisytiharkan dalam skop peringkat blok ditukar, ia jelas akan memberi kesan yang besar pada kod lama. Untuk mengurangkan masalah ketidakserasian yang terhasil, ES6 menetapkan bahawa pelaksanaan penyemak imbas tidak boleh mematuhi peraturan di atas dan mempunyai tingkah laku mereka sendiri ES6

// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }
 
(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }
 
  f();
}());
// Uncaught TypeError: f is not a function
yang membolehkan fungsi diisytiharkan dalam skop peringkat blok.

ES6Pengisytiharan fungsi adalah serupa dengan

, iaitu, ia akan dinaikkan pangkat kepada ketua skop global atau skop fungsi.

Pada masa yang sama, pengisytiharan fungsi juga akan dinaikkan pangkat kepada ketua skop peringkat blok di mana ia berada.
  • Perhatikan bahawa tiga peraturan di atas hanya sah untuk pelaksanaan penyemak imbas
  • Pelaksanaan dalam persekitaran lain tidak perlu mematuhi pengisytiharan fungsi peringkat blok masih dianggap sebagai var.
  • Menurut tiga peraturan ini, dalam persekitaran
  • penyemak imbas, fungsi yang diisytiharkan dalam skop peringkat blok berkelakuan serupa dengan pembolehubah yang diisytiharkan dalam
. Kod yang sebenarnya berjalan dalam contoh di atas adalah seperti berikut.

ES6letMemandangkan tingkah laku berbeza-beza disebabkan oleh persekitaran, pengisytiharan fungsi dalam skop peringkat blok harus dielakkan. Jika ia benar-benar perlu, ia harus ditulis sebagai ungkapan fungsi dan bukannya pernyataan pengisytiharan fungsi.

// 块级作用域内部的函数声明语句,建议不要使用
{
  let a = 'secret';
  function f() {
    return a;
  }
}
 
// 块级作用域内部,优先使用函数表达式
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}

ES6 的块级作用域必须有大括号

如果没有大括号,JavaScript 引擎就认为不存在块级作用域。

// 第一种写法,报错
if (true) let x = 1;
 
// 第二种写法,不报错
if (true) {
  let x = 1;
}

上面代码中,第一种写法没有大括号,所以不存在块级作用域,而let只能出现在当前作用域的顶层,所以报错。第二种写法有大括号,所以块级作用域成立。

函数声明也是如此,严格模式下,函数只能声明在当前作用域的顶层。

// 不报错
'use strict';
if (true) {
  function f() {}
}
 
// 报错
'use strict';
if (true)
  function f() {}

【推荐学习:javascript视频教程

Atas ialah kandungan terperinci Adakah pembolehubah dibalut dalam es6 jika dikira sebagai di dalam blok?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn