JavaScriptの変数、スコープとメモリの問題で理解するためにあなたと記事

ファイル

著者| Jeskson

ソース|ダダフロントエンドビストロ

1

JavaScriptで変数領域は、二つのタイプに分けられます。

基本型値A値の一つは、参照型です。

基本値は、データセグメントの単純型を指し

参照されるオブジェクトの種類はによって提供されている複数の値で構成されています

ファイル

参照型の値がメモリに格納されているオブジェクトは、JavaScriptのメモリ空間ではなく、実際のオブジェクトの実際には、操作対象の参照、オブジェクトを直接操作することはできません。

ファイル

var dada = new Object();
undefined
dada.name = "dada";
"dada"
console.log(dada.name);
VM158:1 dada
undefined

ファイル

var da1 = "da1";
undefined
da1.age = 12;
12
console.log(da1.age);
VM272:1 undefined
undefined

プロパティのプリミティブ型の値が追加されましたが、無駄に、動的にのみ参照型の値に属性を追加するために、それは便利です。

2

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

プリミティブ値をコピーすることは、1つの変数と基準値の他のタイプの変数であります

var da1 = 12;
var da2 = da1;

ファイル

値をDA1 DA2を初期化するために使用される場合DA1格納された値は、12であり、DA2も12の値を保持するが、D2の値の値が12をDA1及び12は完全に独立しています。これらの二つの変数は互いに独立して、任意の操作に参加することができます。

別の変数から参照型変数の値をコピーします。

参照型の値が実際にヒープに格納されたオブジェクトを指すポインタ、複製の参照タイプであり、参照が同じオブジェクトに向けられているので、他の変数は、影響を受けた兄弟も、変数に変化します。

var da3 = new Object();
var da4 = da3;

da3.name = "dada";
console.log(da4.name);

ファイル

DA4のDA3と同じオブジェクトは、 2つの変数が同じオブジェクトを参照するため、name属性は、DA3、DA4アクセスこのプロパティを追加し、結果がダダとして出力されます。

3

パラメータの受け渡し:

JavaScriptでは、すべてのパラメータが値関数によって渡され、パラメータの意味は値によって渡され、外側の内部機能への伝達関数の同じ値をコピーします。

function addNum(num){
 num = num + 1;
 return num;
}
var da5 = 12;
var result = addNum(da5);
console.log(da5);
console.log(result);

ファイル

AddNumつのパラメータの関数numが、このパラメータは実際にはローカル変数の関数です。DA5可変パラメータは、この関数に渡されるように、この関数を呼び出す、変数、パラメータNUMこのaddNumで機能12で使用され、12です()。

function setName(obj) {
 obj.name = "dada";
}
var da6 = new Object();
setName(da6);
console.log(da6.name);

ファイル

検出タイプ:

typeof演算オペレータは、変数は、基本データ型であるかどうか変数が値オブジェクト、またはヌルを有する場合、検出するために使用され、このtypeof演算子の戻りが目的です。

var da7 = "dada";
var da8 = 12;
var da9;
var da10 = null;
var da11 = new Object();

console.log(typeof da7);
console.log(typeof da8);
console.log(typeof da9);
console.log(typeof da10);
console.log(typeof da11);

ファイル

instanceofはオペレータはそれをやってに使用されていますか?オブジェクトの種類を判断します。

// 前提先定义person
console.log(person instanceof Object);
console.log(person instanceof Array);
console.log(person instanceof RegExp);

注意,所有的引用类型的值都是Object的实例,所以检测引用类型的值和Object构造函数时,instanceof操作符都是返回true。instanceof操作符检测基本类型的值,返回的则都是false。因为instanceof检测的都是什么类型的对象。

4

作用域:

当代码在一个环境中执行时,会创建变量对象的一个作用域链,这个作用域链的用途是 保证对执行环境有权访问的多有变量和函数的有序访问。全局执行环境的变量对象都是作用域链中的最后一个对象。

标识符解析是沿着作用域链一级一级地搜索标识符的过程。

var da12 = "dada"

function changeDa(){
 if(da12 === "dada"){
  da12 = "da";
 }else{
  da12 = "da1";
 }
}

changeDa();

console.log(da12);

ファイル

函数changeDa()的作用域链包含两个对象:

它自己的变量对象,和,全局环境的 变量对象。

它自己的 定义着的arguments对象

var da12 = "dada"

function changeDa(){
 var anotherDa = "dadada";
 
 function daDa(){
  var tempDa = anotherDa;
  anotherDa = da12;
  da12 = tempDa;
  // 可以访问 tempDa, anotherDa,da12
 }
 // 这里只能访问 da12,anotherDa
 daDa();
}
// 这里只能访问da12;
changeDa();

ファイル

分析执行环境,有3个,一个为全局环境,一个为changeDa()的局部环境,一个为daDa()的局部环境。

全局环境中有一个变量da12,和一个函数changeDa()。

changeDa()的局部环境中有什么?

一个变量anotherDa,一个名为daDa()的函数。这个函数可以访问全局变量中的da12。

daDa()的局部环境中有什么?

一个变量tempDa,该变量只能在这个环境中访问。

无论是全局环境还是changeDa()的局部环境都无法访问tempDa。

ファイル

ファイル

ファイル

为什么内部的daDa()可以访问其他两个环境中的所有变量呢?

因为那是它们两个的环境是它的父执行环境。

内部环境可以通过作用域链访问所有的外部环境,但是外部环境不能访问内部环境中的任何变量和函数,内部环境都可以向上搜索作用域链,查变量和函数名,不能向下搜索作用域链进入另一个环境。

对于daDa()函数,其中作用域链包含3个对象:

daDa()的变量对象,changeDa()的变量对象,全局变量对象。

过程:

daDa()函数的局部环境,会先开始搜索自己的变量对象中的变量和函数名,如果找不到,会向上搜索上一级的作用域链。

对于changDa()中的环境:

它包含两个对象::一为它自己的变量对象,二为全局变量对象。

即它不能访问daDa()函数的局部环境。

5

执行环境分两种:

一种为全局作用域,一种为局部作用域。

如何理解 try catch 延长了作用域链?

with语句和 try catch 都可以延长作用域链

with比较好理解,而且一般有性能问题,也不推荐用

try catch 是捕获Error对象的时候 会新开一个作用域吗?

还是说 catch的大括号内就是一个能访问到error对象的块级作用域?

try中的代码捕获到错误以后,会把异常对象推入一个可变对象并置于用域的头部,在catch代码块内部,函数的所有局部变量将会被放在第二个作用域对象中,catch中的代码执行完,会立即销毁当前作用域。

什么叫延长作用域链

执行环境(变量对象可谓是它的衍生物)、作用域、作用域链

ファイル

作用域:函数当前执行环境。

作用域链:执行环境产生的变量对象构成。 作用域链是保证函数在执行时能够正确访问需要的变量和函数。

作用域链最外层就是全局作用域

ファイル

var i = 0;
function dada(){
    console.log(i);
}
undefined
dada();
VM656:3 0
undefine

在函数中是没有存在i的,但是在调用这个函数时会返回为0,这是为什么呢?这就是函数作用域链的作用。

延长一: try catch

ファイル

ファイル

(function(window){
   try{
       throw Error("出错误了");
   }catch(e){
      alert(e);  //alert("Error: 出错误了")
   }
   console.log(e);  //undefind
})(window);

在执行catch语句块时,JavaScript自动把其执行环境添加作用域链中,但是该语句块执行完后又自动把该执行环境(变量对象)移除。

alert(e) ==  alert("Error:出现错误");
console.log(e)  ==  undefined;

IE结果:

alert(e)  =>  alert("Error: 出错误了");   

console.log(e) =>   
object Error: 
出错误了{description: "出错误了",message: "出错误了",name: "Error"}

延长二:with

ファイル

function da(){
    console.log(location.href); 
} 

function da(){ 
    with(location){ 
        console.log(href); 
    } 
}

两种方式是等价的:

前提是非严格模式下, 因为严格模式下不支持 with这种方式。

ファイル

延长作用域的表现

ファイル

什么是作用域链?

我的理解就是,根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问。

想要知道js怎么链式查找,就得先了解js的执行环境。

每个函数运行时都会产生一个执行环境,而这个执行环境怎么表示呢?

js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中。

没有块级作用域:

if(true) {
 var da = "dada";
}
console.log(da);

ファイル

ファイル

function add(num1,num2){
    var num = num1 + num2;
    return num;
}
undefined
var result = add(1,2);
undefined
console.log(result);
VM962:1 3
undefined

ファイル

向上查询:

ファイル

var da = "dada";

function getDa(){
 var da = "dadada";
 return da;
}

console.log(getDa());

JavaScript中最常用的垃圾收集方式是标记清除,另一种不太常见的垃圾策略叫做引用计数。

基本型値と基準タイプ値:

プリミティブ値は、参照型のオブジェクトの値をヒープメモリに格納され、スタックメモリに記憶され、メモリ内に固定された空間を占有する別の変数から変数の基本的なタイプの値をコピーし、この値のコピーを作成します。

ないオブジェクト変数の値は、実際に自分自身を含む参照タイプを含むが、物点へのポインタ。

typeof演算子は、オペレータが一種値の参照タイプが何であるかを判断するのinstanceof、プリミティブ型である種類の値を決定します。

実行環境のポイント:

グローバル実行環境、機能の実行環境。

あなたは新しい実行環境に入るたびに、変数と関数の検索スコープチェーンが作成されます。

❤️DOは学習あなたの足跡を残すことを忘れないで[コメント+ +のように収集ポイント]

情報を著者:

[著者]:Jeskson
[オリジナル]公開番号:ダダフロントエンドビストロ。
[福祉]:自己学習教材をまくるに送信されませ公共返信「情報」(シェアへのグループには何がハを言いたい、私は見ませんでした)!
[予約]説明:ソースを明記してください、ありがとう再現!

大規模なテクノロジ・スタックのブログを配置するフロントエンド開発、フロントエンドの開発、PHPの背景知識、ウェブフルスタック技術分野、データ構造とアルゴリズム、およびそう簡単にネットワーク理論を理解するためには、ジュニアパートナーに提示されます。、あなたがサポートして愛の礼儀をありがとうございました!


ローカルコンテンツのこの数はビットを取得しない場合(例:著作権やその他の問題に)、タイムリーにすることができ整流のための私達に連絡し、最初の時間に処理されますしてください。


親指アップしてください!あなたが同意しているので/励ましは、私の文章の最大の力です!

ようこそ注意ダダさんCSDN!

これは、品質、態度のブログです

フロントエンド技術スタック

おすすめ

転載: www.cnblogs.com/dashucoding/p/12099908.html