Rumah hujung hadapan web tutorial js Perkara yang anda tidak tahu tentang JavaScript dari definisi hingga pelaksanaan

Perkara yang anda tidak tahu tentang JavaScript dari definisi hingga pelaksanaan

May 16, 2016 pm 03:21 PM
javascript takrifan melaksanakan

Dari definisi kepada pelaksanaan JavaScript, enjin JS melakukan banyak kerja permulaan pada lapisan pelaksanaan Oleh itu, sebelum mempelajari mekanisme kerja enjin JS, kita perlu memperkenalkan beberapa konsep berkaitan: timbunan persekitaran pelaksanaan, objek global. , persekitaran pelaksanaan, objek berubah-ubah, objek aktif, rantai skop dan skop, dsb. Konsep ini ialah komponen teras enjin JS.

Tujuan artikel ini bukan untuk menerangkan setiap konsep kepada anda secara berasingan, tetapi untuk menjalankan analisis melalui demo mudah, untuk menerangkan secara global setiap perincian enjin JS dari definisi hingga pelaksanaan, dan bagaimana konsep ini disertakan Peranan yang dimainkan.

var x = 1; //定义一个全局变量 x
function A(y){
  var x = 2; //定义一个局部变量 x
  function B(z){ //定义一个内部函数 B
    console.log(x+y+z);
  }
  return B; //返回函数B的引用
}
var C = A(1); //执行A,返回B
C(1); //执行函数B
Salin selepas log masuk

Demo ini ialah penutupan, dan hasil pelaksanaan ialah 4. Di bawah ini kami akan menganalisis JS dalam tiga peringkat: pemulaan global, pelaksanaan fungsi A dan pelaksanaan fungsi B. Mekanisme kerja enjin:

1 Permulaan global

Apabila enjin JS memasukkan sekeping kod boleh laku, ia perlu melengkapkan perkara berikut. tiga tugasan permulaan:

Pertama, cipta objek global (Global Object) Hanya terdapat satu salinan objek ini di seluruh dunia permohonan. Apabila objek global dicipta, objek JS yang biasa digunakan seperti Math, String, Date dan dokumen digunakan sebagai atributnya. Memandangkan objek global ini tidak boleh diakses secara langsung dengan nama, terdapat satu lagi tetingkap atribut, dan tetingkap dihalakan kepada dirinya sendiri, supaya objek global boleh diakses melalui tetingkap. Struktur umum objek global yang disimulasikan dengan kod pseudo adalah seperti berikut:

//创建一个全局对象
var globalObject = { 
  Math:{},
  String:{},
  Date:{},
  document:{}, //DOM操作
  ...
  window:this //让window属性指向了自身
}
Salin selepas log masuk

Kemudian, enjin JS perlu membina tindanan persekitaran pelaksanaan (Timbunan Konteks Pelaksanaan) . Pada masa yang sama, Untuk mencipta persekitaran pelaksanaan global (Konteks Pelaksanaan) EC, dan menolak persekitaran pelaksanaan global ini ke dalam timbunan persekitaran pelaksanaan. Fungsi timbunan persekitaran pelaksanaan adalah untuk memastikan program boleh dilaksanakan dalam susunan yang betul. Dalam JavaScript, setiap fungsi mempunyai persekitaran pelaksanaan sendiri Apabila fungsi dilaksanakan, persekitaran pelaksanaan fungsi akan ditolak ke bahagian atas timbunan persekitaran pelaksanaan dan mendapatkan hak pelaksanaan. Apabila fungsi menyelesaikan pelaksanaan, persekitaran pelaksanaannya dialih keluar dari bahagian atas tindanan dan hak pelaksanaan dikembalikan kepada persekitaran pelaksanaan sebelumnya. Kami menggunakan pseudokod untuk mensimulasikan hubungan antara timbunan persekitaran pelaksanaan dan EC:

var ECStack = []; //定义一个执行环境栈,类似于数组

var EC = {};  //创建一个执行空间,
//ECMA-262规范并没有对EC的数据结构做明确的定义,你可以理解为在内存中分配的一块空间

ECStack.push(EC); //进入函数,压入执行环境
ECStack.pop(EC); //函数返回后,删除执行环境
Salin selepas log masuk

Akhir sekali, enjin JS juga mencipta objek berubah global (Varibale Object) yang dikaitkan dengan EC ) VO, dan titik VO ke objek global VO bukan sahaja mengandungi atribut asal objek global, tetapi juga termasuk pembolehubah yang ditakrifkan secara global dan fungsi A. Pada masa yang sama, apabila mentakrifkan fungsi A, ia juga menambah An. skop atribut dalaman, menunjuk skop kepada VO. Apabila setiap fungsi ditakrifkan, atribut skop dicipta dikaitkan dengannya Skop sentiasa menunjuk kepada persekitaran di mana fungsi itu ditakrifkan. Struktur ECStack pada masa ini adalah seperti berikut:

ECStack = [  //执行环境栈
  EC(G) = {  //全局执行环境
    VO(G):{ //定义全局变量对象
      ... //包含全局对象原有的属性
      x = 1; //定义变量x
      A = function(){...}; //定义函数A
      A[[scope]] = this; //定义A的scope,并赋值为VO本身
    }
  }
];
Salin selepas log masuk

2. Jalankan fungsi A

Apabila pelaksanaan memasuki A( 1) , enjin JS perlu menyelesaikan kerja berikut:

Mula-mula, enjin JS akan mencipta persekitaran pelaksanaan EC fungsi A, dan kemudian EC akan ditolak ke bahagian atas timbunan persekitaran pelaksanaan dan mendapatkan hak pelaksanaan. Pada masa ini, terdapat dua persekitaran pelaksanaan dalam tindanan persekitaran pelaksanaan, iaitu persekitaran pelaksanaan global dan persekitaran pelaksanaan fungsi A. Persekitaran pelaksanaan A berada di bahagian atas tindanan, dan persekitaran pelaksanaan global berada di bahagian bawah. daripada timbunan. Kemudian, cipta rantai skop (Rantai Skop) fungsi A. Dalam JavaScript, setiap persekitaran pelaksanaan mempunyai rantai skop sendiri untuk resolusi pengecam Apabila persekitaran pelaksanaan dibuat, rantai skopnya adalah objek yang terkandung dalam skop daripada fungsi yang sedang dijalankan.

Seterusnya, enjin JS akan mencipta Objek Pengaktifan (Objek Pengaktifan) AO bagi fungsi semasa Objek aktiviti di sini memainkan peranan objek berubah, tetapi ia dipanggil secara berbeza dalam fungsi (anda boleh berfikir bagi objek pembolehubah ialah konsep umum, dan objek aktif ialah cabang daripadanya), AO mengandungi parameter formal fungsi, objek hujah, objek ini, dan takrif pembolehubah tempatan dan fungsi dalaman, dan kemudian AO akan ditolak ke bahagian atas rantai skop. Perlu diingat bahawa apabila mentakrifkan fungsi B, enjin JS juga akan menambah atribut skop kepada B dan menghalakan skop kepada persekitaran di mana fungsi B ditakrifkan Persekitaran di mana fungsi B ditakrifkan ialah objek aktif AO . AO terletak di hujung hadapan senarai terpaut Memandangkan senarai terpaut disambungkan dari hujung ke hujung, skop fungsi B menghala ke seluruh rantai skop A. Mari kita lihat struktur ECStack pada masa ini:

ECStack = [  //执行环境栈
  EC(A) = {  //A的执行环境
    [scope]:VO(G), //VO是全局变量对象
    AO(A) : { //创建函数A的活动对象
      y:1,
      x:2, //定义局部变量x
      B:function(){...}, //定义函数B
      B[[scope]] = this; //this指代AO本身,而AO位于scopeChain的顶端,因此B[[scope]]指向整个作用域链
      arguments:[],//平时我们在函数中访问的arguments就是AO中的arguments
      this:window //函数中的this指向调用者window对象
    },
    scopeChain://链表初始化为A[[scope]],然后再把AO加入该作用域链的顶端,此时A的作用域链:AO(A)->VO(G)
  },
  EC(G) = {  //全局执行环境
    VO(G):{ //创建全局变量对象
      ... //包含全局对象原有的属性
      x = 1; //定义变量x
      A = function(){...}; //定义函数A
      A[[scope]] = this; //定义A的scope,A[[scope]] == VO(G)
    }
  }
];
Salin selepas log masuk

三、 执行函数B

函数A被执行以后,返回了B的引用,并赋值给了变量C,执行 C(1) 就相当于执行B(1),JS引擎需要完成以下工作:

首先,还和上面一样,创建函数B的执行环境EC,然后EC推入执行环境栈的顶部并获取执行权。 此时执行环境栈中有两个执行环境,分别是全局执行环境和函数B的执行环境,B的执行环境在栈顶,全局执行环境在栈的底部。(注意:当函数A返回后,A的执行环境就会从栈中被删除,只留下全局执行环境)然后,创建函数B的作用域链,并初始化为函数B的scope所包含的对象,即包含了A的作用域链。最后,创建函数B的活动对象AO,并将B的形参z, arguments对象 和 this对象作为AO的属性。此时ECStack将会变成这样:

ECStack = [  //执行环境栈
  EC(B) = {  //创建B的执行环境,并处于作用域链的顶端
    [scope]:AO(A), //指向函数A的作用域链,AO(A)->VO(G)
    var AO(B) = { //创建函数B的活动对象
      z:1,
      arguments:[],
      this:window
    }
    scopeChain://链表初始化为B[[scope]],再将AO(B)加入链表表头,此时B的作用域链:AO(B)->AO(A)-VO(G)
  },
  EC(A), //A的执行环境已经从栈顶被删除,
  EC(G) = {  //全局执行环境
    VO:{ //定义全局变量对象
      ... //包含全局对象原有的属性
      x = 1; //定义变量x
      A = function(){...}; //定义函数A
      A[[scope]] = this; //定义A的scope,A[[scope]] == VO(G)
    }
  }
];
Salin selepas log masuk

当函数B执行“x+y+z”时,需要对x、y、z 三个标识符进行一一解析,解析过程遵守变量查找规则:先查找自己的活动对象中是否存在该属性,如果存在,则停止查找并返回;如果不存在,继续沿着其作用域链从顶端依次查找,直到找到为止,如果整个作用域链上都未找到该变量,则返回“undefined”。从上面的分析可以看出函数B的作用域链是这样的:

AO(B)->AO(A)->VO(G)
因此,变量x会在AO(A)中被找到,而不会查找VO(G)中的x,变量y也会在AO(A)中被找到,变量z 在自身的AO(B)中就找到了。所以执行结果:2+1+1=4.

简单的总结语

了解了JS引擎的工作机制之后,我们不能只停留在理解概念的层面,而要将其作为基础工具,用以优化和改善我们在实际工作中的代码,提高执行效率,产生实际价值才是我们的真正目的。就拿变量查找机制来说,如果你的代码嵌套很深,每引用一次全局变量,JS引擎就要查找整个作用域链,比如处于作用域链的最底端window和document对象就存在这个问题,因此我们围绕这个问题可以做很多性能优化的工作,当然还有其他方面的优化,此处不再赘述,本文仅当作抛砖引玉吧!

以上就是本文的全部内容,希望对大家的学习有所帮助。

【相关教程推荐】

1. JavaScript视频教程
2. JavaScript在线手册
3. bootstrap教程

Kenyataan Laman Web ini
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

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Dec 17, 2023 pm 02:54 PM

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata Dec 17, 2023 pm 05:30 PM

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Definisi dan fungsi kunci utama komposit MySQL Definisi dan fungsi kunci utama komposit MySQL Mar 15, 2024 pm 05:18 PM

Kunci utama komposit dalam MySQL merujuk kepada kunci utama yang terdiri daripada pelbagai medan dalam jadual, yang digunakan untuk mengenal pasti setiap rekod secara unik. Tidak seperti kunci utama tunggal, kunci utama komposit dibentuk dengan menggabungkan nilai berbilang medan. Apabila membuat jadual, anda boleh menentukan kunci utama komposit dengan menentukan berbilang medan sebagai kunci utama. Untuk menunjukkan definisi dan fungsi kunci utama komposit, kami mula-mula membuat jadual bernama pengguna, yang mengandungi tiga medan: id, nama pengguna dan e-mel, dengan id ialah kunci utama dan pengguna yang meningkat secara automatik

Apa itu Discuz? Definisi dan pengenalan fungsi Discuz Apa itu Discuz? Definisi dan pengenalan fungsi Discuz Mar 03, 2024 am 10:33 AM

"Meneroka Discuz: Definisi, Fungsi dan Contoh Kod" Dengan perkembangan pesat Internet, forum komuniti telah menjadi platform penting untuk orang ramai mendapatkan maklumat dan bertukar pendapat. Di antara banyak sistem forum komuniti, Discuz, sebagai perisian forum sumber terbuka yang terkenal di China, digemari oleh majoriti pembangun dan pentadbir laman web. Jadi, apa itu Discuz? Apakah fungsi yang ada padanya, dan bagaimana ia boleh membantu tapak web kami? Artikel ini akan memperkenalkan Discuz secara terperinci dan melampirkan contoh kod khusus untuk membantu pembaca mengetahui lebih lanjut mengenainya.

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Dec 17, 2023 pm 05:13 PM

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Jan 05, 2024 pm 06:08 PM

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Pengenalan kepada antara muka PHP dan cara mentakrifkannya Pengenalan kepada antara muka PHP dan cara mentakrifkannya Mar 23, 2024 am 09:00 AM

Pengenalan kepada antara muka PHP dan bagaimana ia ditakrifkan PHP ialah bahasa skrip sumber terbuka yang digunakan secara meluas dalam pembangunan Web Ia fleksibel, mudah dan berkuasa. Dalam PHP, antara muka ialah alat yang mentakrifkan kaedah biasa antara pelbagai kelas, mencapai polimorfisme dan menjadikan kod lebih fleksibel dan boleh digunakan semula. Artikel ini akan memperkenalkan konsep antara muka PHP dan cara mentakrifkannya, dan menyediakan contoh kod khusus untuk menunjukkan penggunaannya. 1. Konsep antara muka PHP Antara muka memainkan peranan penting dalam pengaturcaraan berorientasikan objek, mentakrifkan aplikasi kelas

Definisi dan penggunaan aksara lebar penuh Definisi dan penggunaan aksara lebar penuh Mar 25, 2024 pm 03:33 PM

Apakah aksara lebar penuh? Dalam sistem pengekodan komputer, aksara dwilebar ialah kaedah pengekodan aksara yang mengambil dua kedudukan aksara standard. Sejajar dengan itu, kaedah pengekodan aksara yang menduduki kedudukan aksara standard dipanggil aksara separuh lebar. Aksara lebar penuh biasanya digunakan untuk input, paparan dan pencetakan aksara Cina, Jepun, Korea dan Asia yang lain. Dalam kaedah input bahasa Cina dan penyuntingan teks, senario penggunaan aksara lebar penuh dan aksara separuh lebar adalah berbeza. Penggunaan aksara lebar penuh Kaedah input Cina: Dalam kaedah input Cina, aksara lebar penuh biasanya digunakan untuk memasukkan aksara Cina, seperti aksara Cina, simbol, dsb.

See all articles