目次
1️⃣ スコープとクロージャ
2️⃣ プロトタイプとプロトタイプ チェーン
3️⃣ 异步和单线程
ホームページ ウェブフロントエンド jsチュートリアル JS の 3 つの山の詳細な説明: スコープとクロージャ、プロトタイプとプロトタイプ チェーン、非同期とシングル スレッド

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

Apr 18, 2023 pm 05:16 PM
javascript フロントエンド

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 までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ Mar 16, 2024 pm 12:09 PM

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ 今日のインターネットの急速な発展の時代において、フロントエンド開発はますます重要になっています。 Web サイトやアプリケーションのエクスペリエンスに対するユーザーの要求がますます高まっているため、フロントエンド開発者は、より効率的で柔軟なツールを使用して、応答性の高いインタラクティブなインターフェイスを作成する必要があります。フロントエンド開発の分野における 2 つの重要なテクノロジーである PHP と Vue.js は、組み合わせることで完璧なツールと見なされます。この記事では、PHP と Vue の組み合わせと、読者がこれら 2 つをよりよく理解し、適用できるようにするための詳細なコード例について説明します。

フロントエンドの面接官からよく聞かれる質問 フロントエンドの面接官からよく聞かれる質問 Mar 19, 2024 pm 02:24 PM

フロントエンド開発のインタビューでは、HTML/CSS の基本、JavaScript の基本、フレームワークとライブラリ、プロジェクトの経験、アルゴリズムとデータ構造、パフォーマンスの最適化、クロスドメイン リクエスト、フロントエンド エンジニアリング、デザインパターン、新しいテクノロジーとトレンド。面接官の質問は、候補者の技術スキル、プロジェクトの経験、業界のトレンドの理解を評価するように設計されています。したがって、候補者はこれらの分野で自分の能力と専門知識を証明するために十分な準備をしておく必要があります。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

Django はフロントエンドですか、バックエンドですか?それをチェックしてください! Django はフロントエンドですか、バックエンドですか?それをチェックしてください! Jan 19, 2024 am 08:37 AM

Django は、迅速な開発とクリーンなメソッドを重視した Python で書かれた Web アプリケーション フレームワークです。 Django は Web フレームワークですが、Django がフロントエンドなのかバックエンドなのかという質問に答えるには、フロントエンドとバックエンドの概念を深く理解する必要があります。フロントエンドはユーザーが直接対話するインターフェイスを指し、バックエンドはサーバー側プログラムを指し、HTTP プロトコルを通じてデータと対話します。フロントエンドとバックエンドが分離されている場合、フロントエンドとバックエンドのプログラムをそれぞれ独立して開発して、ビジネス ロジックとインタラクティブ効果、およびデータ交換を実装できます。

Go 言語のフロントエンド テクノロジーの探求: フロントエンド開発の新しいビジョン Go 言語のフロントエンド テクノロジーの探求: フロントエンド開発の新しいビジョン Mar 28, 2024 pm 01:06 PM

Go 言語は、高速で効率的なプログラミング言語として、バックエンド開発の分野で広く普及しています。ただし、Go 言語をフロントエンド開発と結びつける人はほとんどいません。実際、フロントエンド開発に Go 言語を使用すると、効率が向上するだけでなく、開発者に新たな視野をもたらすことができます。この記事では、フロントエンド開発に Go 言語を使用する可能性を探り、読者がこの分野をよりよく理解できるように具体的なコード例を示します。従来のフロントエンド開発では、ユーザー インターフェイスの構築に JavaScript、HTML、CSS がよく使用されます。

Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たすかを探る Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たすかを探る Mar 19, 2024 pm 06:15 PM

Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たしているかを調べるには、具体的なコード例が必要です。インターネットとモバイル アプリケーションの急速な発展に伴い、フロントエンド テクノロジーの重要性がますます高まっています。この分野では、強力なバックエンド プログラミング言語としての Golang も重要な役割を果たします。この記事では、Golang がどのようにフロントエンド テクノロジーと組み合わされるかを検討し、具体的なコード例を通じてフロントエンド分野での可能性を実証します。フロントエンド分野における Golang の役割は、効率的で簡潔かつ学びやすいものとしてです。

See all articles