検索
ホームページウェブフロントエンドjsチュートリアル一緒にクロージャについて知りましょう

一緒にクロージャについて知りましょう

#関連する学習に関する推奨事項:

JavaScript ビデオ チュートリアル

まえがき

# 終わりに は、フロントエンド開発者にとって常に回避できないハードルであり、好むと好まざるにかかわらず、仕事や面接で遭遇することがあります。クロージャについての理解は人それぞれ異なりますので、ここでは私自身のクロージャについての理解をお話します。 (理解に矛盾がある場合は、ご自身でご参照ください)

クロージャの定義方法

定義を与える前に、他の人がどのようにクロージャを定義しているかを見てみるとよいでしょう:

関数オブジェクトはスコープ チェーンを通じて相互に関連付けることができ、関数本体内の変数は関数スコープに保存できます。この機能は、コンピュータ サイエンスの文献では「クロージャ」と呼ばれています - JavaScript オーソリティ ガイド (第 6 版)

#クロージャは、別の関数のスコープ内の変数にアクセスできる関数です。クロージャを作成する一般的な方法は、別の関数の中に関数を作成することです。 --Advanced Programming in JavaScript (Third Edition)

関数が現在の字句スコープ内にある場合でも、関数がその字句スコープを記憶してアクセスできる場合、クロージャが発生します。ドメインの外。 -- あなたの知らない JavaScript (第 1 巻)

上記の段落の説明は同じではありませんが、注意深く味わってみると、いくつかの共通点を見つけることができます。これらの中で最も重要なのは、異なるスコープ間の

接続 です。もちろん、上記の定義を直接引用することもできます (結局のところ、上記の定義は比較的信頼できるものです)。ここでは、著者は最後の段落の定義を好み、書籍「あなたが知らない JavaScript (第 1 巻)」を強く推奨します。 、注意深く繰り返し読む価値があります。

クロージャにどのようなナレッジ ポイントが関係しているか

定義を与えるだけでは十分ではなく、どのようなナレッジ ポイントが内部的に関係しているのかも調査する必要があります。筆者が役立つと思った知識を以下に挙げます。

スコープとスコープ チェーン

実は、著者は皆さんがこれについて考えたことがあることを知っています (いいえ、これを考えたことがない人は誰もいません)。これで誰もが

scope を知ることができました。ここではそれを簡単に説明し、そのプロセスを見ていきます。

スコープ: 変数を名前で検索するための一連のルール。グローバルスコープ、関数スコープ、ブロックスコープの3種類に分かれます。

注目すべきはES6の新しい仕様であるブロックスコープです。中括弧

{} 内の let および const を使用して定義された変数はスコープにバインドされ、中括弧の外側からはアクセスできません。 注: 中括弧の先頭と let 変数宣言の前の間に 一時的なデッド ゾーンがあります (この点はこの記事の範囲外です) 。 スコープ チェーン: 異なるスコープが一緒にトラップされると、スコープ チェーンが形成されます。検索方向は内側から外側であることに注意してください。

スコープの検索方向が内側から外側になるのはなぜですか?これは興味深い質問です。個人的には、js の実行関数がスタックにプッシュされる方法によって決まると思います (少し話が逸れたように感じます。興味のある友人は情報を確認してください)。

字句スコープ

関数が別の関数スコープ内の変数にアクセスできる (または現在のスコープを覚えていて、現在のスコープの外にアクセスできる) 理由の重要なポイント

字句スコープ### 仕事で。これは非常に重要ですが、誰もがこの知識ポイントを知っているわけではないので、ここで簡単に説明しましょう。

プログラミングの世界には、スコープの 2 つの作業モードがあります。1 つは、ほとんどのプログラミング言語で使用される 字句スコープ で、もう 1 つはその逆です。ダイナミック スコープ

(これはこの記事の範囲外です)。

字句スコープ: 変数とブロックのスコープはコードを書くときに決定され、オブジェクトや呼び出される場所によって変更されません (これは反対)。

それ以外の場合は、例を挙げてみましょう:
let a = 1;
function fn(){
    let a = 2;
    function fn2(){
        console.log(a);
    }
 return fn2;
}

let fn3 = fn();
fn3();
上記の定義から、

fn

はクロージャ関数
fn3 ## であることがわかります。

#fn2

のポインタ アドレスを取得しました。

fn3 が実行されると、実際には fn2 が実行され、内部の a 変数は、スコープ チェーンの検索ルールでは、検出されるのは fn スコープ内の変数 a であるため、最終出力は 1 ではなく 2 になります。 (下の図をご覧ください) 話は逸れますが、字句スコープを欺くにはどうすればよいでしょうか?

字句スコープは静的ですが、それを騙して動的な効果を実現する方法はまだあります。 一緒にクロージャについて知りましょう

第一种方法是使用eval. eval可以把字符串解析成一个脚本来运行,由于在词法分析阶段,无法预测eval运行的脚本,所以不会对其进行优化分析。

第二种方法是with. with通常被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。with本身比较难掌握,使用不当容易出现意外情况(如下例子),不推荐使用 -.-

function Fn(obj){
    with(obj){
        a = 2;
    }
}

var o1 = {
    a:1
}
var o2 = {
    b:1
}

Fn(o1);
console.log(o1.a); //2
Fn(o2);
console.log(o2.a); //undefined;
console.log(a); //2 a被泄漏到全局里面去了
// 这是with的一个副作用, 如果当前词法作用域没有该属性,会在全局创建一个

闭包能干啥?

闭包的使用场景可多了,平时使用的插件或者框架,基本上都有闭包的身影,可能您没留意过罢了。下面笔者列举一些比较常见的场景。

  1. 模拟私有变量和方法,进一步来说可以是模拟模块化;目前常用的AMD,CommonJS等模块规范,都是利用闭包的思想;

  2. 柯里化函数或者偏函数;利用闭包可以把参数分成多次传参。如下面代码:

// 柯里化函数
function currying(fn){
    var allArgs = [];

    function bindCurry(){
        var args = [].slice.call(arguments);
        allArgs = allArgs.concat(args);
        return bindCurry;
    }
    bindCurry.toString = function(){
        return fn.apply(null, allArgs);
    };

    return bindCurry;
}
  1. 实现防抖或者节流函数;

  2. 实现缓存结果(记忆化)的辅助函数:

// 该方法适合缓存结果不易改变的函数
const memorize = fn => {
    let memorized = false;
    let result = undefined;
    return (...args) => {
        if (memorized) {
            return result;
        } else {
            result = fn.apply(null,args); 
            memorized = true;
            fn = undefined;
            return result;
        }
    };
};

如何区分闭包?

说了那么多,我怎么知道自己写的代码是不是闭包呢?先不说新手,有些代码的确隐藏的深,老鸟不仔细看也可能发现不了。 那有没有方法可以帮助我们区分一个函数是不是闭包呢?答案是肯定的,要学会善于利用周边的工具资源,比如浏览器。

打开常用的浏览器(chrome或者其他),在要验证的代码中打上debugger断点,然后看控制台,在scope里面的Closure(闭包)里面是否有该函数(如下图)。

一緒にクロージャについて知りましょう

闭包真的会导致内存泄漏?

答案是有可能。内存泄漏的原因在于垃圾回收(GC)无法释放变量的内存,导致运行一段时候后,可用内存越来越少,最终出现内存泄漏的情况。常见的内存泄漏场景有4种:全局变量;闭包引用;DOM事件绑定;不合理使用缓存。其中,闭包导致内存泄漏都是比较隐蔽的,用肉眼查看代码判断是比较难,我们可用借助chrome浏览器的Memory标签栏工具来调试。由于篇幅问题,不展开说明了,有兴趣自己去了解一下如何使用。

想了解更多编程学习,敬请关注php培训栏目!

以上が一緒にクロージャについて知りましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はjuejinで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
ブラウザを超えて:現実世界の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はサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

JavaScriptをインストールするにはどうすればよいですか?JavaScriptをインストールするにはどうすればよいですか?Apr 05, 2025 am 12:16 AM

JavaScriptは、最新のブラウザにすでに組み込まれているため、インストールを必要としません。開始するには、テキストエディターとブラウザのみが必要です。 1)ブラウザ環境では、タグを介してHTMLファイルを埋め込んで実行します。 2)node.js環境では、node.jsをダウンロードしてインストールした後、コマンドラインを介してJavaScriptファイルを実行します。

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

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

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

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 中国語版

SublimeText3 中国語版

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

mPDF

mPDF

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

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません