Rumah > hujung hadapan web > tutorial js > Penjelasan terperinci tentang tiga gunung JS: skop dan penutupan, prototaip dan rantai prototaip, tak segerak dan benang tunggal

Penjelasan terperinci tentang tiga gunung JS: skop dan penutupan, prototaip dan rantai prototaip, tak segerak dan benang tunggal

青灯夜游
Lepaskan: 2023-04-18 17:16:51
ke hadapan
1179 orang telah melayarinya

js ialah tulang belakang bahagian hadapan. Jadi, adakah anda tahu apakah tiga gunung besar javascript itu?

1️⃣ Skop dan penutupan

作用域 merujuk kepada konteks semasa kod dan kawalan pembolehubah dan keterlihatan fungsi dan kitaran hayat. Fungsi terbesar adalah untuk mengasingkan pembolehubah, jadi pembolehubah dengan nama yang sama dalam skop yang berbeza tidak akan bercanggah.

作用域链 bermakna jika nilai tidak ditemui dalam skop semasa, ia akan menanyakan skop atas sehingga skop global Rantaian yang dibentuk oleh proses carian sedemikian dipanggil rantai skop. [Pembelajaran yang disyorkan: tutorial video javascript]

Skop boleh disusun ke dalam struktur hierarki dan skop kanak-kanak boleh mengakses skop induk, tetapi bukan sebaliknya.

skop boleh dibahagikan kepada empat jenis: 全局作用域, 模块作用域, 函数作用域, 块级作用域

Skop global: Kod boleh diakses di mana-mana dalam atur cara, seperti objek tetingkap. Walau bagaimanapun, pembolehubah global akan mencemarkan ruang nama global dan mudah menyebabkan konflik penamaan.

Skop modul: Tiada definisi modul dalam sintaks awal js kerana skrip asal adalah kecil dan ringkas. Kemudian, apabila skrip menjadi semakin kompleks, penyelesaian modular muncul (modul AMD, CommonJS, UMD, ES6, dll.). Biasanya modul ialah fail atau skrip, dan modul ini mempunyai skop bebasnya sendiri.

Skop fungsi: Seperti namanya, skop yang dicipta oleh fungsi. Penutupan dijana dalam skop ini, yang akan kami perkenalkan secara berasingan kemudian.

Skop peringkat blok: Memandangkan promosi pembolehubah js mempunyai kelemahan reka bentuk seperti liputan berubah dan pencemaran berubah, ES6 memperkenalkan kata kunci skop peringkat blok untuk menyelesaikan masalah ini. Kes biasa ialah gelung for bagi let dan gelung for bagi var.

// var demo
for(var i=0; i<10; i++) {
    console.log(i);
}
console.log(i); // 10

// let demo
for(let i=0; i<10; i++) {
    console.log(i);
}
console.log(i); //ReferenceError:i is not defined
Salin selepas log masuk

Setelah memahami skop, mari kita bincangkannya 闭包: Fungsi A mengandungi fungsi B, dan fungsi B menggunakan pembolehubah fungsi A, kemudian fungsi B dipanggil A penutupan atau penutupan ialah fungsi yang boleh membaca pembolehubah dalaman fungsi A.

Dapat dilihat bahawa penutupan adalah produk di bawah skop fungsi Penutupan akan dibuat pada masa yang sama dengan fungsi luar dilaksanakan Ia adalah gabungan fungsi dan rujukannya kepada keadaan persekitaran sekeliling. Dalam erti kata lain, penutupan ialah fungsi dalam yang tidak melepaskan pembolehubah fungsi luar .

Ciri-ciri penutupan:

  • Fungsi wujud dalam fungsi
  • Fungsi dalaman boleh mengakses skop fungsi luar; 🎜>Parameter dan pembolehubah tidak akan GC dan sentiasa berada dalam ingatan;
  • Terdapat penutupan hanya jika terdapat memori.
  • Jadi menggunakan penutupan akan menggunakan memori, dan penggunaan yang tidak betul akan menyebabkan masalah limpahan memori Sebelum keluar dari fungsi, semua pembolehubah tempatan yang tidak digunakan perlu dipadamkan. Jika bukan untuk keperluan tertentu, adalah tidak bijak untuk mencipta fungsi dalam fungsi. Penutupan mempunyai kesan negatif terhadap prestasi skrip dari segi kelajuan pemprosesan dan penggunaan memori.

Senario aplikasi penutupan diringkaskan di bawah:

// demo1 输出 3 3 3
for(var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
} 
// demo2 输出 0 1 2
for(let i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}
// demo3 输出 0 1 2
for(let i = 0; i < 3; i++) {
    (function(i){
        setTimeout(function() {
        console.log(i);
        }, 1000);
    })(i)
}
Salin selepas log masuk
/* 模拟私有方法 */
// 模拟对象的get与set方法
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
    privateCounter += val;
}
return {
    increment: function() {
    changeBy(1);
    },
    decrement: function() {
    changeBy(-1);
    },
    value: function() {
    return privateCounter;
    }
}
})();
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */
Salin selepas log masuk
/* setTimeout中使用 */
// setTimeout(fn, number): fn 是不能带参数的。使用闭包绑定一个上下文可以在闭包中获取这个上下文的数据。
function func(param){ return function(){ alert(param) }}
const f1 = func(1);setTimeout(f1,1000);
Salin selepas log masuk
/* 生产者/消费者模型 */
// 不使用闭包
// 生产者
function producer(){
    const data = new(...)
    return data
}
// 消费者
function consumer(data){
    // do consume...
}
const data = producer()

// 使用闭包
function process(){
    var data = new (...)
    return function consumer(){
        // do consume data ...
    }
}
const processer = process()
processer()
Salin selepas log masuk
Saya nampaknya faham konsep penutupan Tetapi nampaknya ada sesuatu yang hilang? Maknanya masih belum habis. Saya juga tersesat dalam penutupan, tetapi selepas membaca kitaran hayat penutupan, saya mendapati diri saya semula.
/* 实现继承 */
// 以下两种方式都可以实现继承,但是闭包方式每次构造器都会被调用且重新赋值一次所以,所以实现继承原型优于闭包
// 闭包
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}
// 原型
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};
Salin selepas log masuk

Penjelasan terperinci tentang tiga gunung JS: skop dan penutupan, prototaip dan rantai prototaip, tak segerak dan benang tunggalSelepas belajar, mari kita buat ujian cepat

function test(a, b){
  console.log(b);
  return {
    test: function(c) {
      return test(c,a);
    }
  }
}

var a = test(100);a.test(101);a.test(102);
var b = test(200).test(201).test(202);
var c = test(300).test(301);c.test(302);

// undefined  100  100
// undefined  200 201
// undefined  300 301
Salin selepas log masuk
2️⃣ Prototaip dan rantai prototaip

Di sana adalah objek Jika terdapat

, setiap objek akan memulakan atribut di dalamnya, iaitu prototaip (prototaip), dan atribut serta kaedah yang dikongsi disimpan dalam prototaip. Apabila kita mengakses sifat sesuatu objek, enjin js akan menyemak dahulu sama ada objek semasa mempunyai sifat ini Jika tidak, ia akan menyemak sama ada objek prototaipnya mempunyai sifat ini, dan seterusnya sehingga objek terbina dalam objek diambil semula. Proses carian sedemikian membentuk konsep 原型. 原型链Perkara yang paling penting untuk memahami prototaip ialah untuk menjelaskan hubungan antara __proto__, prototaip dan pembina Mari kita lihat beberapa konsep dahulu:

  • __proto__属性在所有对象中都存在,指向其构造函数的prototype对象;prototype对象只存在(构造)函数中,用于存储共享属性和方法;constructor属性只存在于(构造)函数的prototype中,指向(构造)函数本身。
  • 一个对象或者构造函数中的隐式原型__proto__的属性值指向其构造函数的显式原型 prototype 属性值,关系表示为:instance.__proto__ === instance.constructor.prototype
  • 除了 Object,所有对象或构造函数的 prototype 均继承自 Object.prototype,原型链的顶层指向 null:Object.prototype.__proto__ === null
  • Object.prototype 中也有 constructor:Object.prototype.constructor === Object
  • 构造函数创建的对象(Object、Function、Array、普通对象等)都是 Function 的实例,它们的 __proto__ 均指向 Function.prototype。

看起来是不是有点乱??别慌!!一张图帮你整理它们之间的关系

Penjelasan terperinci tentang tiga gunung JS: skop dan penutupan, prototaip dan rantai prototaip, tak segerak dan benang tunggal

相同的配方再来一刀

const arr = [1, 2, 3];
arr.__proto__ === Array.prototype; // true
arr.__proto__.__proto__ === Object.prototype; // true
Array.__proto__ === Function.prototype; // true
Salin selepas log masuk

3️⃣ 异步和单线程

JavaScript 是 单线程 语言,意味着只有单独的一个调用栈,同一时间只能处理一个任务或一段代码。队列、堆、栈、事件循环构成了 js 的并发模型,事件循环 是 JavaScript 的执行机制。

为什么js是一门单线程语言呢?最初设计JS是用来在浏览器验证表单以及操控DOM元素,为了避免同一时间对同一个DOM元素进行操作从而导致不可预知的问题,JavaScript从一诞生就是单线程。

既然是单线程也就意味着不存在异步,只能自上而下执行,如果代码阻塞只能一直等下去,这样导致很差的用户体验,所以事件循环的出现让 js 拥有异步的能力。

Penjelasan terperinci tentang tiga gunung JS: skop dan penutupan, prototaip dan rantai prototaip, tak segerak dan benang tunggal

更多编程相关知识,请访问:编程教学!!

Atas ialah kandungan terperinci Penjelasan terperinci tentang tiga gunung JS: skop dan penutupan, prototaip dan rantai prototaip, tak segerak dan benang tunggal. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:juejin.cn
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan