検索
ホームページウェブフロントエンドjsチュートリアルJS の 3 つの山の詳細な説明: スコープとクロージャ、プロトタイプとプロトタイプ チェーン、非同期とシングル スレッド

js はフロントエンドのバックボーンとして機能します。では、JavaScript の三大山とは何かご存知ですか?

1️⃣ スコープとクロージャ

スコープ は現在のコードを参照します コンテキスト変数と関数の可視性とライフサイクルを制御します。最大の機能は変数を分離することで、異なるスコープにある同じ名前の変数が競合しないようにします。

スコープ チェーン は、現在のスコープで値が見つからない場合、グローバル スコープに到達するまで上位スコープをクエリすることを意味します。このような検索プロセスはチェーンです。形成されたものをスコープチェーンと呼びます。 [推奨学習: JavaScript ビデオ チュートリアル ]

スコープは階層構造にスタックでき、子スコープは親スコープにアクセスできますが、その逆はできません。

スコープは 4 つのタイプに細分できます: グローバル スコープ モジュール スコープ 関数スコープ #、ブロックレベル スコープ

##グローバル スコープ: コードはプログラム内にあり、どこからでもアクセスできます。ウィンドウオブジェクトなど。ただし、グローバル変数はグローバル名前空間を汚染し、名前の競合を引き起こしやすくなります。

モジュール スコープ: 元のスクリプトは小さくて単純だったため、初期の js 構文にはモジュール定義がありませんでした。その後、スクリプトがますます複雑になるにつれて、モジュール型ソリューション (AMD、CommonJS、UMD、ES6 モジュールなど) が登場しました。通常、モジュールはファイルまたはスクリプトであり、このモジュールには独自の独立したスコープがあります。

関数スコープ: 名前が示すように、関数によって作成されるスコープ。クロージャはこのスコープ内で生成されますが、これについては後で別途紹介します。

ブロックレベルのスコープ: js 変数のプロモーションには変数カバレッジや変数汚染などの設計上の欠陥があるため、ES6 ではこれらの問題を解決するためにブロックレベルのスコープ キーワードが導入されています。典型的なケースは、let の for ループと var の for ループです。

// 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

スコープを理解したら、それについて話しましょう

クロージャ: 関数 A には関数 B が含まれており、関数 B は関数 A の変数を使用し、次に関数 B Aクロージャまたはクロージャは、関数 A の内部変数を読み取ることができる関数です。

クロージャは関数スコープ内のプロダクトであることがわかります。クロージャは外側の関数の実行と同時に作成されます。関数とそのバンドルへの参照の組み合わせです。周囲の環境状態。つまり、

クロージャは、内部関数 によって外部関数の変数が解放されないことです。

クロージャの特徴:

    関数内に関数があり、
  • 内部関数は外部関数のスコープにアクセスできます。
  • パラメータと変数は GC されず、常にメモリ内に存在します。
  • クロージャはメモリがある場所にのみ存在します。
したがって、クロージャを使用するとメモリが消費され、不適切に使用するとメモリ オーバーフローの問題が発生するため、関数を終了する前に、未使用のローカル変数をすべて削除する必要があります。特定のニーズがない場合、関数内に関数を作成することは賢明ではなく、クロージャーは処理速度とメモリ消費の点でスクリプトのパフォーマンスに悪影響を及ぼします。

クロージャの適用シナリオを以下にまとめます。

// 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)
}
/* 模拟私有方法 */
// 模拟对象的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 */
/* setTimeout中使用 */
// setTimeout(fn, number): fn 是不能带参数的。使用闭包绑定一个上下文可以在闭包中获取这个上下文的数据。
function func(param){ return function(){ alert(param) }}
const f1 = func(1);setTimeout(f1,1000);
/* 生产者/消费者模型 */
// 不使用闭包
// 生产者
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()
/* 实现继承 */
// 以下两种方式都可以实现继承,但是闭包方式每次构造器都会被调用且重新赋值一次所以,所以实现继承原型优于闭包
// 闭包
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;
};

クロージャの概念は理解しているようですが、何かが足りないようですか?その意味はまだ終わっていません。私もクロージャで迷っていましたが、クロージャのライフサイクルを読んだ後、再び自分自身を発見しました。

JS の 3 つの山の詳細な説明: スコープとクロージャ、プロトタイプとプロトタイプ チェーン、非同期とシングル スレッド

学習したら、簡単なテストをしてみましょう

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

2️⃣ プロトタイプとプロトタイプ チェーン

オブジェクト

prototype があり、各オブジェクトは内部のプロパティであるプロトタイプ(プロトタイプ)を初期化し、プロトタイプには共有プロパティやメソッドが格納されます。オブジェクトのプロパティにアクセスすると、JS エンジンはまず現在のオブジェクトにこのプロパティがあるかどうかを確認します。ない場合は、プロトタイプ オブジェクトにこのプロパティがあるかどうかを確認し、Object 組み込みオブジェクトが取得されるまで同様に確認します。このような検索プロセスは、プロトタイプ チェーンの概念を形成しました。

プロトタイプを理解するために最も重要なことは、__proto__、プロトタイプ、コンストラクターの関係を明確にすることです。最初にいくつかの概念を見てみましょう:

  • __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。

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

JS の 3 つの山の詳細な説明: スコープとクロージャ、プロトタイプとプロトタイプ チェーン、非同期とシングル スレッド

相同的配方再来一刀

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

3️⃣ 异步和单线程

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

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

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

JS の 3 つの山の詳細な説明: スコープとクロージャ、プロトタイプとプロトタイプ チェーン、非同期とシングル スレッド

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

以上がJS の 3 つの山の詳細な説明: スコープとクロージャ、プロトタイプとプロトタイプ チェーン、非同期とシングル スレッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は掘金社区で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。