ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptの変数とスコープの詳しい説明

JavaScriptの変数とスコープの詳しい説明

jacklove
jackloveオリジナル
2018-06-11 17:47:491695ブラウズ

天安門、紫禁城、万里の長城に行ったことがないということは、北京に行ったことがないということになります。 JS の変数のスコープを理解していないと、JS を学習していないのと同じです。 JS 変数スコープの重要性を自分で学びましょう。ヒント: この記事を読むときは、必ずコメントを読んでください。

JS は弱く型付けされた (緩やかに型付けされた) 言語です。つまり、本質的に異なり、独自のものです。
変数スコープを説明する前に、まずJSの変数について理解しましょう。 JS の変数は他の言語とは大きく異なります。JS 変数は緩やかな (必須ではない) 性質を持っているため、特定の段階で特定のタイプの値を保持する名前にすぎません。

JS 変数には、基本データ型 (値型) と参照データ型 (複合データ型) の 2 つの異なるデータ型が含まれています。

基本データ型の値はスタックメモリに保存されます。参照データ型の値はヒープ メモリに格納され、参照データ型のポインタ アドレスのみがスタック メモリに保持されます。
値には 5 つの基本的なタイプがあります: 未定義、Null、ブール、数値、文字列です。基本データ型の値はスタック メモリに格納されます。

//在栈内存中开辟一块空间存储值为"laotie"的变量namevar name="laotie";//在栈内存中开辟一块空间存储值为"laotie"的变量name2var name2=name;//name与name2是相对独立的,所以改变name2的值为"xiaozhang",而name的值不会受到影响var name2="xiaozhang";
console.log(name);//laotieconsole.log(name2);//xiaozhang

参照型をもう一度見てみましょう:

/*在栈内存中存放 obj的地址
* 其值存放在堆内存中。
* 栈内存的地址的指向堆内存中的值。*/var obj={
    name:"zhangpeiyue"}/*将obj的地址赋值给obj2
所以在栈内存中存储的地址与obj的地址相同,
obj与obj2共享同一个值。
*/var obj2=obj;
obj2.name="xiaozhang";//因为obj与obj2共享同一个值,所以上行代码改变的是同一个值console.log(obj.name);//xiaozhang
 //你也可以认为obj即为obj2,引用类型比较的是地址,因此为trueconsole.log(obj==obj2);//true
次に、基本データ型と参照型の比較をそれぞれ見てみましょう
  • 基本データ型の比較、比較は値です:

//基本数据类型比较的是值,只要值相等比较结果即为truevar a=1;var b=1;console.log(a==b);//truevar c=2;var d=c;console.log(c==d);//true
  • 参照型 比較、比較はアドレスです:

var obj={
    age:12}var obj2={
    age:12}//引用类型比较的是地址,而不是值。//由于每次创建的引用类型地址都不同,所以结果为falseconsole.log(obj==obj2);//falsevar obj3={
    age:12}//将obj3的地址赋值给obj4。所以地址相同var obj4=obj3;//由于比较的是地址,且obj3与obj4的地址相同,所以结果为trueconsole.log(obj3==obj4);
関数のパラメータとしての基本型と参照型の問題を見てみましょう
  • 基本型はパラメータとして使用され、パラメータはローカル変数です

/*接收的所有基本数据类型,接收的是其值。
接收的参数都是函数体中的局部变量。
在函数体内改变值,对外部不会产生任何影响*/function fn(a){
    a+=1;
    console.log(a);//14}
var a=13;fn(a);
console.log(a);//13
  • 参考データ型はパラメータとして使用され、パラメータはグローバル変数です

/*引用数据类型传递的是引用地址,
因此函数体中的obj与函数外的obj的引用地址相同。
所以函数体中的obj与函数外的obj共享同一值,
改变其中一个值,其它的也会随之改变
*/function fn(obj){
    obj.name="laowang"
    console.log(obj.name);//laowang}
var obj={
    name:"laotie"}fn(obj);
console.log(obj.name);//laowang
最後にスコープについて話しましょう! JS 変数のスコープとは、変数の影響を受けるスコープを指します。 JSのスコープはグローバルスコープとローカルスコープ(関数スコープ)に分かれます。グローバル スコープで定義された変数はグローバル変数であり、ローカル スコープで定義された変数はローカル変数です。

グローバル スコープは、Web ブラウザーで最も周辺的に定義されたスコープであり、ウィンドウ オブジェクトを指します。したがって、グローバル スコープで定義された変数と関数は、ウィンドウ オブジェクトのプロパティとメソッドとして考えることができます。

var color="red";//定义一个全局colorfunction fn(){
    color="blue";//全局函数可以在函数内访问}fn();
console.log(color);//blue
  • グローバル変数と関数はすべて window オブジェクトの属性とメソッドです。

var color="red";//定义一个全局colorfunction fn(){    color="blue";//全局函数可以在函数内访问}window.fn();
console.log(window.color);//blue
  • 関数スコープで宣言された変数は、パラメータを渡すことでグローバルスコープで宣言された変数と同じ名前になります

var color="yellow";//定义全局变量colorfunction fn(){    //在函数体内如果拥有指定的变量,就不会去外层查找
    var color="red";//这里是局部变量color,外面是访问不到的哦
    console.log(color);//red}fn();
console.log(color);//yellow
  • 。渡されるパラメータは基本型であり、パラメータは関数本体のローカル変数です。渡されるパラメータは参照型であり、パラメータは関数本体内のグローバル変数です。記事の冒頭で説明したので、ここでは説明しません。

  • 関数本体にサブ関数がある場合、その関数のみがサブ関数にアクセスできます。

var color="green";function fn(){
    //子函数是建议以下划线开头
    function _fn2(){
        var color2="orange";
        console.log(color);//green
        console.log(color2);//orange
    }
    _fn2();//_fn2()的作用域在fn()内}
fn();
_fn2();//在此处调用fn2()是调取不到的

注: コードがスコープ内で実行される場合、スコープ チェーンと呼ばれるものが存在します。その役割は、変数とメソッドへのアクセスの順序性を確保することです。つまり、現在の実行環境に指定された変数やメソッドが存在する場合は周辺検索を行わず、存在しない場合は見つかるまで周辺検索を行います。見つからない場合は、エラーが報告されます。指定された変数とメソッドをレイヤーごとに検索する動作により、一連の操作が形成されます。このチェーンがスコープ チェーンです。ローカル変数へのアクセスは、指定された変数を外部から探す (ルックアップする) 必要がないため、グローバル変数よりもはるかに高速です。
* JS にはブロックレベルのスコープがありません。いわゆるブロックレベルのスコープは、if、for、その他のステートメントの中括弧で囲まれたコードを指します。

if(true){    var name="zhang";
}
console.log(name);//zhang

関数内で var キーワードを使用せずに変数を宣言すると、その変数はグローバル変数になります。ただし、この動作は名前の競合を引き起こしやすいため、すべての人に使用することはお勧めできません。

function fn(){    //此处a=12相当于window.a=12。
    a=12;//声明一个不带var关键字的变量}fn();
console.log(a);//12

これは、fn 関数がウィンドウ環境で実行されるため、関数本体の a=12 は window.a=12 を実行することと同じになります。そして window は JS の最上位オブジェクトです。値 12 の属性をトップレベルのオブジェクトに追加したと考えることもできます。したがって、変数 a はグローバル変数になります。
さらに、関数本体内の変数が var キーワードを通じて宣言されている場合、その変数はローカル変数となり、関数本体内でのみアクセスでき、関数本体外からはアクセスできません。

function fn(){
    var a=12;
    console.log(a);//12}fn();
console.log(a);//报错:a is not defined
  • スコープに関する Alibaba からのインタビューの質問を共有します:

var obj = {
    b: 2};var fn = function () {};
fn.c = 3;function test(x, y, z) {
    x = 4;
    y.b = 5;
    z.c = 6;    return z;
}
test(a, obj, fn);
console.log(a + obj.b + fn.c);//12
变量的生命周期

所谓变量的生命周期指的是变量由声明到销毁。
对于全局变量来讲,其生命周期是永久的,除非我们主动去销毁这个全局变量。而在函数体内声明的局部变量,当函数运行完以后,局部变量就失去了任何价值,它们也会随着函数的执行完毕而销毁。

var fn=function(){
    var a=1;//退出函数后,局部变量a会销毁
    console.log(a);
}fn();
  • JS环境中分配的内存一般有如下生命周期
    内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
    内存使用:即读写内存,也就是使用变量、函数等
    内存回收:使用完毕,由垃圾回收自动回收不再使用的内存 

  • 本文讲解了JavaScript的变量及作用域,更多相关内容请关注php中文网。

  • 相关推荐:

  • 关于$.ajax()方法参数详解

  • 讲解数学对象Math相关内容

  • 关于JS和JSP的区别讲解

以上がJavaScriptの変数とスコープの詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。