JS高度なプログラミング第4章 - Liteの

はじめに:ピュアハンド!自分のアイデアを書き換えるためによると!これは第2のブラシで、ノートの完全な夏をしたいだろうが、あまりにも高価、その後、メモを書くために本を使用し、いつかまた失われたことがあります。==それでいいやブログ


 第4章:変数、スコープとメモリの問題


4.1基本的な値型と参照型:

  基本型の値と基準値型:ECMAScriptの変数は、異なるデータ型の2つの値を含んでいてもよいです。

  • 値の基本的なタイプ:
    • これは、単純なデータセグメントを指します。
    • タイプ:未定義、ヌル、ブール値、数値 、文字列。これは、5つの基本データ型である値にアクセスすることにより、あなたが変数に格納された実際の値を操作できるように、。
    • メモリ内の固定サイズのフットプリント、それが中に保存されているスタックメモリに。
  • 参照型の値:
    • これは、それらのオブジェクトが複数の値で構成されてもよいことをいいます。
    • 型:Object。値がメモリに格納された参照型のオブジェクトであり、JSメモリ空間は、オブジェクトを直接操作することはできません。操作では、オブジェクトは、実際の操作オブジェクトである参照ではなく、実際のオブジェクト。参照型の値ので、参照アクセスによるの。
    • 値は、従って、ヒープメモリに格納されたオブジェクトです。

4.1.1動的属性:

  ほぼ同じ値で基本型値と参照型を定義します。変数を作成し、この変数を割り当てます。しかし、操作の後に同じではありません。参照型にのみ、動的に属性を追加するために価値を与えることができます。

 

  • :(参照型)は削除し、そのプロパティとメソッドを変更することができ、そのプロパティとメソッドを追加することができます

   例:VAR人=新しいオブジェクト(); //オブジェクトを作成し、変数の人に格納します。

     person.name =「ニック」; //オブジェクトの名前と呼ばれる属性、およびこのプロパティに割り当てられている文字列値「ニック」を追加します。

     console.log(person.name); //「ニック」、オブジェクトはこのプロパティを破壊しない場合には常に存在してきました。

  • 基本タイプは、実質的に属性の値に追加しないタイプ。

4.1.2変数の値をコピーします。

  一つの変数から別の変数値と基準タイプにコピーベースタイプ値は、異なるがある場合。

  • 基本的なタイプ:

   例:VAR NUM1 = 5;

  VaRのNUM2 = NUM​​1は; //値NUM1のNUM2の初期化を使用するために、NUM2も値5が含まれています。しかし、55 NUM2 5は、NUM1とNUM2 NUM1 5の単なるコピーでお互いに影響を与えません、完全に独立しています。

     前の変数オブジェクトをコピーします。

   
   
NUM1 5

   )、その値を渡す:(コピー新しいスペースを開放した後、変数オブジェクト

   
NUM2 5
NUM1 5

 

  • 参照型は:また、新しい変数のためのスペースの割り当てに変数オブジェクトに格納された値をコピーします。これは実際にはポインタの値のコピー、およびヒープに格納されているオブジェクトへのポインタであることを除いて。

        コピー操作の後、二つの変数は、実際に同じオブジェクトを参照してください。このように一つの変数を変更すると、他の変数に影響を与える、種類を参照します。

   例:VAR OBJ1 =新しいオブジェクト(); //オブジェクトの新しい変数OBJ1インスタンスを保存します。

        VAR OBJ2 = OBJ1; //その値が同じオブジェクトにOBJ1 OBJ2、すなわちobj1とobj2の点にコピーされます。

     obj1.name =「ニック」。

     console.log(obj2.name); //「ニック」、name属性がOBJ1に追加された後、このプロパティはobj2がアクセスすることができます。

 複製前に変数オブジェクト:この(オブジェクトタイプ)ヒープメモリのオブジェクトを指すオブジェクト1

   
   
OBJ1 (オブジェクトタイプ)

 ヒープオブジェクトオブジェクト1(すなわち、同一のオブジェクト)への2つの(オブジェクトタイプ)メモリ・ポインタ:オブジェクト変数をコピーした後

   
obj2が (オブジェクトタイプ)
OBJ1 (オブジェクトタイプ)

 

4.1.3引数:

  ESすべての関数パラメータがされている値によって渡される、すなわち、内部パラメータ関数をコピーする機能の外に別の変数からコピーされた値と等価です。

  • 基本タイプ:変数の同じ基本的なタイプの送信コピーなどのプリミティブな値。
    • 基本的なタイプのパラメータ値を渡す場合、渡された値は、ローカル変数(すなわち名前付きパラメータ、引数要素またはオブジェクト)にコピーされます。
    • レプリケーションの基本的なタイプは、それぞれ他のパラメータ引数に干渉する。
  • 参照型:変数の同じタイプの参照コピーとして渡されたリファレンスのタイプの値。
    • 伝送パラメータ値のタイプに言及する場合、置くメモリ内の値をアドレスのローカル変数にコピーされ、そう変更は、ローカル変数、外部関数に反映されます。
    • オブジェクトのヒープメモリにそのアドレスの値で充填された基準オブジェクト変数のタイプを、格納します。だから、ときに、同じメモリアドレスへのオブジェクト変数のコピー、obj1とobj2がポイント。
    • したがって、送信パラメータ、同じメモリアドレスを指し示すパラメータ引数に、属性は、形状パラメータを変更すると、引数になります。パラメータそのものが直接変更した場合(例えば、パラメータメモリに再割り当て:オブジェクトを再定義し、そのオブジェクトは、新しい属性を定義します)、その後、時間パラメータの変更は、引数には影響しません。だから、随時渡された値によって渡された参照データ型で!

   例:関数addTen(NUM){//パラメータNUM、機能の実際にはローカル変数パラメータ。

      A + = 10。

      確かに返します。

     }

     カウント数= 20でした。  

     VaRの結果= addTen(カウント); // addTenを関数を呼び出すときに、変数countは、関数にパラメータとして渡され、変数countの値が20で、値20は、その後、(パラメータNUMにコピーされ、ローカル変数またはパラメータまたは引数が指定されたオブジェクト機能で使用するための一つの要素)。

     console.log(カウント)。// 20。

     console.log(結果); // 30は、内部関数のnumがプラス10が、この変更は、外部変数の機能はカウントには影響しません。(シモンズ:NUMは参照によって渡された場合、その後、コースの数は30になるだろう)

 

   例:関数のsetName(OBJ){

      obj.name =「ニック」。

     }

     VaRの人=新しいオブジェクト(); //オブジェクトを作成し、変数の人に格納します。

     setName(人); //そして、後の関数は、変数はOBJにコピーされます()のsetNameに渡されます。この関数内、OBJと引用した人は、同じオブジェクトです。(これが意味することである:この変数は、同じオブジェクトを参照した値、OBJアクセスによって渡されます)

     console.log(person.name)。//」ニック」

 

   例:関数のsetName(OBJ){

      obj.name =「ニック」。

      OBJ =新しいオブジェクト();

      obj.name =「ゲイリー」。

     }

     VaRの人=新しいオブジェクト();

     setName(人)。

     console.log(person.name); //「ニック」は、関数内のパラメータの値を変更して説明するが、元の参照は依然として変わりません。値によって渡されないので。

 

4.1.4検出器タイプ:

  • 与えられた変数--typeofのデータ型を検出し、基本データ型を検出するためにそれを使用するのがベストです。
    • 「未定義」 - この値が定義されていない場合。
    • 「ブール」 - この値はブール値である場合には、
    • 「文字列」 - この値は文字列である場合には、
    • 「数」 - この値が数値の場合、
    • 「オブジェクト」 - この値はオブジェクトまたはnullの場合。
    • 「機能」 - この値が関数であれば!関数はオブジェクトですが、typeofを区別することによって機能することはできませんが。

    如:VAR =「いくつかの文字列」のメッセージ。

      警告(メッセージの種類)。//「文字列」

      警告(ヌルのタイプ); //」オブジェクト」

  • それはタイプ--instanceofの対象が何であるかを時間を知りたい検出基準タイプ。
    • 構文:結果=可変のinstanceofコンストラクタ(コンストラクタ)
    • 例如:にconsole.log(オブジェクトのinstanceof人)。
    • 基準値とオブジェクト型のコンストラクタを検出し、instanceofは常にtrueを返します。
    • 基本データ型は検出を取る場合は、falseが返されます。

 

4.2スコープと実行環境:

  各実行環境変数オブジェクトが関連付けられているが、すべての環境が定義された変数および関数は、このオブジェクトに格納されています。私たちは、オブジェクトにアクセスすることはできませんが。

  • グローバル実行環境:環境への相当の最周辺のウィンドウオブジェクトなので、すべてのグローバル変数と関数は、作成されたウィンドウオブジェクトのプロパティとメソッドの通りです。
  • 各関数は、独自の実行環境を持っています。ストリームは、機能を実行入ると、関数は、スタックの周囲環境にプッシュされ、機能が実行された後、スタックがその環境をポップアップ表示され、実行環境の制御は、以前のクーポンに戻ります。
  • 実行環境内のすべてのコードは、環境が破壊されて終了した後、また破壊されるすべての変数と関数の定義を保存します。(アプリケーションが終了するまでグローバル言葉が破壊されます)。
  • スコープチェーン:コードは、環境内で実行されると、それは変数オブジェクトが作成されますが、スコープチェーンで、使用はすべての変数と関数実行環境へのアクセス権を持っていると秩序のアクセスを確保することです。
    • スコープチェーンの前は常に、現在実行中の変数オブジェクトコード環境です。この環境が関数であれば、それは変数オブジェクトとしてアクティブなオブジェクトです。アクティブオブジェクトは、一番最初に(グローバル非存在下でargumentsオブジェクト、)変数が含まれています。
    • 環境から成る次スコープ鎖可変オブジェクト、その後次の目的は、次の環境を含む変数です。これは、グローバルな実行環境に拡張されました。グローバルスコープチェーンの実行環境変数オブジェクトは、常に最後のオブジェクトです。
  • ステージによってスコープチェーンステージ沿っ識別子サーチ処理:識別子を解析します。検索プロセスは、常にスコープチェーンの前から始まり、その後、あなたは(識別子が見つからない場合、通常はエラーになります)識別子を見つけるまで、バック後方段階的。
    • 例:VAR色=「青」; //地球環境、可変色および機能changeColorがあります() 

        ローカル環境の関数changeColorは(){// changeColor()、名前が付けられ、anotherColorのswapColors()関数と呼ばれる変数があり、changeColor()変数の色は、地球環境にアクセスすることができます。

          VAR anotherColor =「赤「。

          関数swapColorsローカル環境の(){// swapColor()、変数tempColorがあり、この環境では、この変数へのアクセスのみをすることができます。(その環境がその2つの親の実行環境であるため)swapColor()は他の二つの変数のすべての内部環境にアクセスすることができます。

            VAR tempColor = anotherColor; //地球環境やchangeColor(両方)は、ローカル環境変数tempColorにアクセスすることはできません。

            anotherColor =色。

            色= tempColor。

            //ここでは、色、anotherColorとtempColorにアクセスすることができます。

          }

          swapColor(); //ここでは、色、anotherColorにアクセスすることができます。

        }

        changeColor(); //ここでは色のみにアクセスすることができます。

    • 以下は、スコープチェーンの一例です。

   

 

4.2.1スコープチェーンを拡張します。

  実行環境の種類のみ、グローバル及びローカル(関数)が、しかし、スコープチェーンを拡張する他の方法があります。

  • 以下这两个语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。(即当执行流进入下列任意一个语句时,作用域链会得到加长)
    • try-catch语句的catch块(会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明)
      • 例:try { fn (); } catch (ex) { handleError (ex); }  //try发送错误就跳转到catch语句,catch会创建一个新的变量对象,其中包含被抛出的错误对象的声明。(即这个对象只能内部访问)
    • with语句(会将指定的对象添加到作用域链中),with 语句的原本用意是为逐级的对象访问提供命名空间式的速写方式,但最好不用,因为我们可以用变量来实现。
      • 例:function buildUrl () {

            var qs = "?debug=true";

            with (location) {  //location对象现在为作用域链的最前端,由于with关联了location对象,所以location在with内部相当于window对象的地位,所以获取location里的属性可以不写location。

              var url = href + qs;  //href实际引用的是location.href,qs实际引用的是buildUrl () 中定义的那个变量。url是with语句内部定义的,因此url成为函数执行环境的一部分,所以就可以作为函数的值被返回。

            }

            return url;  //因为with语句不是函数,所以url还是属于buildUrl () 函数的,所以就可以作为函数的值被返回。

          }

 

4.2.2 ES5没有块级作用域,ES6有let、const:

  • 例:if (true) {  //if是语句不是函数

      var color = "blue";

     }

     alert (color);  //"blue"

   上面这段代码对于JS来说,if语句中的变量声明会将变量添加到当前的执行环境(即全局环境)。

  • 例:for (var i = 0; i < 10; i++) {  //for是语句不是函数

      doSomething (i);

     }

     alert (i);  //10

   上面这段代码对于JS来说,for语句创建的变量i即使在for循环执行结束之后,也依旧会存在于循环外部的执行环境中。

  • 声明变量:使用var声明的变量会自动被添加到最接近的环境中。在函数内部,最接近的函数就是函数的局部函数;在with语句中,最接近的环境是函数环境。如果初始化变量时没有使用var声明,该变量会自动被添加到全局环境。
    • function add (num1, num2) {

        var sum = num1 + num2;

        return sum;

      }

      var result = add (10, 20);  //30

      alert (sum);  //由于sum是var声明的,因此全局访问不到,导致错误。

    • function add (num1, num2) {

          sum = num1 + num2;

        return sum;

      }

      var result = add (10, 20);  //30

      alert (sum);  //30,因为变量sum在初始化的时候没有使用var声明,该变量会自动被添加到全局环境。所以可以在全局环境里访问到sum=30;

  • 查询标识符:

  当在某个环境中为了读取或写入而引用一个标识符时,必须通过搜索来确定该标识符实际代表什么。搜索过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符。

  如果在搜索过程中发现局部环境中存在了同名标识符,那么就不会去使用位于父环境中的标识符啦。

 

4.3 垃圾收集:

  JS具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存。(自动找出那些不再继续使用的变量,任何释放其占用的内存),为此垃圾收集器会按照固定的时间间隔(或者代码执行中预定的收集时间),周期性地执行这一操作。

  局部变量的生命周期:局部变量只在函数执行的过程中存在。这个过程中,会为局部变量在栈(或堆)内存上分配相应的空间以存储它们的值,然后再函数中使用这些变量,直到函数执行结束。所以这个时候局部变量就没有存在的必要了。因此释放它们的内存以供将来使用。

  • 常见的垃圾收集方式是标记清除:当变量进入环境时(比如在函数中声明一个变量),就将这个变量标记为“进入环境”(不可以释放进入环境的变量所占用的内存!!),因为只要执行流进入相应的环境,就可能会用到它们。当变量离开环境时,则将其标记为“离开环境”
  • 第二个不常用的方式时引用计数,这里不说先。
  • 性能问题:先不说。
  • 管理内存(解除引用):确保占用最少的内存可以让页面获得更好的性能,而优化内存占用最好的方式时为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用——解除引用。
    • 局部变量:会在它们离开执行环境时自动被解除引用。
    • 全局变量:设置null来释放引用,让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
    • 好处是不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效的回收内存,应该及时解除不再使用的全部对象、全局对象属性以及循环引用变量的引用。

おすすめ

転載: www.cnblogs.com/XiaoYEBLog/p/11218251.html