国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ECMA_作用域深入&This關(guān)鍵字

Harriet666 / 475人閱讀

摘要:預(yù)解析聲明告知瀏覽器在全局作用域中有一個變量名為的變量。執(zhí)行代碼的就是棧內(nèi)存,作用域也是棧內(nèi)存。關(guān)鍵字在中主要研究都是函數(shù)中的中的代表的是當(dāng)前行為執(zhí)行的主體方法,函數(shù),事件中的上下文代表的是當(dāng)前行為執(zhí)行的環(huán)境區(qū)域例如小明在沙縣小吃吃蛋炒飯。

基本認(rèn)識

數(shù)據(jù)類型

基本數(shù)據(jù)類型

string, number, null, boolean, undefined

引用數(shù)據(jù)類型

object: [],{},/d/,Date
function

函數(shù)類型

開辟內(nèi)存空間

把函數(shù)中的代碼當(dāng)作字符串先存儲

把內(nèi)存地址復(fù)制給當(dāng)前函數(shù)名

JS引擎

當(dāng)瀏覽器加載HTML頁面時候,首先會先提供一個供全局JS代碼執(zhí)行的環(huán)境 --> 全局作用域 (global、window

函數(shù)先把代碼體當(dāng)作字符串,存儲到堆內(nèi)存,引用賦值給當(dāng)前函數(shù)名。
執(zhí)行會開辟棧,來執(zhí)行當(dāng)前代碼。

預(yù)解析

聲明declare:告知瀏覽器在全局作用域中有一個 變量名 為 xxx 的變量。(如果一個變量只是聲明了但是沒有賦值,默認(rèn)值:undefind)
定義defined:對變量進(jìn)行賦值

預(yù)解析

在當(dāng)前的作用域中,JS代碼執(zhí)行之前,瀏覽器首先會默認(rèn)的把所有的帶var,和function的進(jìn)行提前的聲明或定義

var 和 function 關(guān)鍵字

對于帶var 和 function 關(guān)鍵字的在預(yù)解析的時候操作
var -> 在預(yù)解析的時候只是提前聲明了
function -> 在預(yù)解析的時候提前的聲明了 + 定義 都完成了。

預(yù)解析只發(fā)生在當(dāng)前的作用域下進(jìn)行解析。
一開始只會對widnow環(huán)境下的進(jìn)行預(yù)解析,只有函數(shù)執(zhí)行的時候才會對函數(shù)中的進(jìn)行解析

JS內(nèi)存的分類

根據(jù)作用分類

棧內(nèi)存: 用來提供一個供JS代碼執(zhí)行的環(huán)境 --> 作用域 (全局作用域/私有的作用域,和函數(shù))
堆內(nèi)存: 用來存儲引用數(shù)據(jù)類型的值 --> 對象存儲的是屬性名和屬性值,函數(shù)存儲的是代碼字符串

作用域鏈

區(qū)分私有變量和全局變量

在全局作用域下聲明(預(yù)解析的時候)的變量是全局變量

在私有作用域中聲明的變量和函數(shù)形參都是私有變量.

在私有作用域中,代碼執(zhí)行的時候遇到了一個變量,首先需要確定是否為私有變量,如果是私有變量,那么和外面的作用域沒有任何關(guān)系;

函數(shù)執(zhí)行

當(dāng)函數(shù)執(zhí)行的時候(直接目的:讓函數(shù)體中的代碼執(zhí)行),首先會形成一個新的私有作用域。
執(zhí)行代碼的就是棧內(nèi)存,作用域也是棧內(nèi)存。

如果有形參,先給形成賦值

進(jìn)行私有作用域預(yù)解析

私有作用域的代碼從上至下執(zhí)行

函數(shù)形成一個新的私有作用域保護(hù)了里面的私有變量不受外界的干擾。(外邊變量修改不了私有變量的,私有變量的也修改不了外邊變量)

作用域鏈

如果不是私有變量,則往當(dāng)前的上級作用域進(jìn)行查找,如果上級沒有則繼續(xù)查找,則一直找到頂級作用域(window)。

全局變量的細(xì)節(jié)

在全局作用域中,帶var和不帶var的關(guān)系

區(qū)別:帶var的可以進(jìn)行預(yù)解析,所以在賦值的前面執(zhí)行不會報錯;
不帶var的是不能進(jìn)行預(yù)解析的,在前面使用該變量名會報錯。

場景在全局作用域下,帶var和不帶var的關(guān)系:

console.log(num); // undefiend
var num = 10;    
console.log(num2); // 報錯
num2 = 10;

關(guān)系:先判斷是否是全局變量,如果是就輸出,如果不是會再去判斷是否是window底下的屬性。
num2=10; --> 相當(dāng)于給window增加了一個叫做num2的屬性名,屬性值是10
var num=10; --> 首先它相當(dāng)于給全局作用域增加了一個全局變量num,但是不僅如此,也相當(dāng)于給window增加了一個屬性num,屬性值10

var num = 10;
console.log(num); // 10
console.log(window.num); // 10

num2 = 10;
console.log(num2); // 10 // window.num2
console.log(window.num2); // 10

第一種:

function fn() {
  console.log(total); // 報錯
  total = 100;
}
fn();
console.log(total); // 100

第二種:

function fn() {
  total = 100;
}
fn();
console.log(total); // 100

私有作用域中出現(xiàn)的一個變量不是私有的,則往上級作用域進(jìn)行查找,上級沒有則繼續(xù)向上尋找,一直找到window為止,如果window下也沒有,分為兩種情況:

獲取值:console.log(total); --> 報錯(JS中,如果在不進(jìn)行任何特殊處理的情況下,報錯之后,代碼退出執(zhí)行)

設(shè)置值: total = 100; --> 相當(dāng)于給window增加了一個屬性名total,屬性值為100

預(yù)解析機制

in操作符:"num" in window 判斷num是否為window這個對象的一個屬性,是的話返回true,不是返回false

預(yù)解析的時候不管你的條件是否成立,都要把帶var的進(jìn)行提前聲明

if (!("num" in window)) { // 預(yù)解析,var num --> window.num  // "num" in window 為true
  var num = 12;
}
console.log(num);  // undefined

函數(shù)表達(dá)式

匿名函數(shù)表達(dá)式:把函數(shù)定義的部分當(dāng)作一個值賦值給變量/元素.

fn(); // 報錯
var fn = function() { // 匿名函數(shù)之函數(shù)表達(dá)式 // 把函數(shù)定義的部分當(dāng)作一個值賦給變量/元素的某一個事件
  console.log("ok");
}
fn(); // ok


fn(); // ok
function fn() {
  console.log("ok");
}
fn(); // ok

自執(zhí)行函數(shù)

自執(zhí)行函數(shù):定義和執(zhí)行一起完成

自執(zhí)行函數(shù)在全局作用域下不進(jìn)行預(yù)解析,當(dāng)代碼執(zhí)行到當(dāng)前位置的時候定義和執(zhí)行一起完成了。

(function(num) {})(100);
~function(num) {}(100);
!function(num) {}(100);
+function(num) {}(100);
!function(num) {}(100);

return 后續(xù)的語句

函數(shù)體中reutrn后續(xù)的代碼雖然不在執(zhí)行了,但是需要進(jìn)行預(yù)解析。
return 的函數(shù)是返回值,并不需要預(yù)解析。

function fn() {
  console.log(num); // undefined
  return function () { console.log(this); } // return 跟著的語句不會預(yù)解析
  var num = 100; // var 進(jìn)行預(yù)解析
}

var t = fn();
console.log(t());

函數(shù)權(quán)重高

在JS中如果變量名和函數(shù)名重復(fù),是沖突。函數(shù)級別高,使用的是函數(shù)。

console.log(fn);
function fn() {
}
var fn = 10;

在預(yù)解析的時候,如果名字已經(jīng)聲明過了,不需要重新聲明,但是需要重新賦值.

// 聲明 + 定義: fn: oxfff11
// 聲明:var fn;(不需要重新聲明)
// 聲明 + 定義: fn: oxfff222
// ---> fn: oxfff222
fn(); // 2
function fn() {console.log(1);}
fn(); // 2
var fn = 10; // 修改作用域值
fn(); // 報錯
function fn() {console.log(2);}
fn(); // 停止執(zhí)行
查找作用域

如何查找當(dāng)前作用域的上級作用域

看當(dāng)前函數(shù)是在哪個作用域下定義的,那么它的上級作用域就是誰。(和函數(shù)在哪里執(zhí)行的沒有任何的關(guān)系)
函數(shù)作用域,查詢變量,定義的位置有關(guān).

var num = 12;
function fn() {
  var num = 120;
  return function() {
    console.log(num);
  }
}

var f = fn();
f(); // 120  // window環(huán)境下執(zhí)行,先找父級,后找window  
// 匿名函數(shù)也是堆內(nèi)存。

~function() {
  var num = 111;
  f();
}();

內(nèi)存釋放&作用域銷毀

堆內(nèi)存釋放

堆內(nèi)存作用:存放引用內(nèi)存的屬性值
釋放方法:null空對象指針

對象數(shù)據(jù)類型或者函數(shù)數(shù)據(jù)類型在定義的時候首先都會開辟一個堆內(nèi)存,
堆內(nèi)存有一個引用的地址,如果外邊有變量知道了這個地址,這個內(nèi)存就被占用,不能銷毀。

var obj1 = {name: 1};
var obj2 = obj1;
// 想讓堆內(nèi)存釋放/銷毀,只需要把所有的引用它的變量賦值為null即可。如果堆內(nèi)存沒有任何東西被占用了,那么瀏覽器會在空閑的時候,會把它銷毀。
// 垃圾回收
obj1 = null;
obj2 = null;

棧內(nèi)存釋放或作用域銷毀

棧內(nèi)存作用:存放作用域

作用域:
全局作用域(瀏覽器天然開辟,瀏覽器關(guān)閉的時候才釋放)
私有作用域(只有函數(shù)執(zhí)行,才會產(chǎn)生私有做作用域)

銷毀情況

一般情況下,函數(shù)執(zhí)行會形成一個新的私有的作用域,當(dāng)私有作用域中的代碼執(zhí)行完成后,當(dāng)前作用域都會主動進(jìn)行釋放和銷毀。
作用域有被子級作用域引用,父級的私有變量不能銷毀。

函數(shù)執(zhí)行返回了一個引用數(shù)據(jù)類型值,并且在函數(shù)外邊一個變量接收,這種情況下一般形成的私有作用域都不能被銷毀。(閉包)

在一個私有的作用域中,給DOM元素的事件綁定方法,一般情況下,私有作用域都不會銷毀。( DOM對象,在執(zhí)行性函數(shù)中被引用)

返回的回調(diào)函數(shù)再次被執(zhí)行,不會被立即銷毀內(nèi)存 (不立即銷毀)

// 1: 引用類型的返回值,被外界引用
function fn() {
  var num = 10;
  return function() {

  }
}
var f = fn();

// 2:  DOM對象,在執(zhí)行性函數(shù)中被引用
var oDiv = document.getElementById("div1");
~function() {
  oDiv.onclick = function() {}
}(); // 當(dāng)自執(zhí)行函數(shù)形成的這個私有作用域也不銷毀


// 3: 返回的回調(diào)函數(shù)再次被執(zhí)行,不會被立即銷毀內(nèi)存  (不立即銷毀)
function fn() {
  var num = 10;
  return function() {

  }
}
fn()(); // 首先fn執(zhí)行,返回一個回調(diào)函數(shù)對應(yīng)的內(nèi)存地址,然后緊接著讓返回的小函數(shù)再執(zhí)行。
// 返回的回調(diào)函數(shù)再次被執(zhí)行,不會被立即銷毀內(nèi)存,當(dāng)返回的回調(diào)函數(shù)執(zhí)行完成后,瀏覽器會在空閑的時候銷毀。
function fn() {
  var i = 10;
  return function(n) {
    console.log(n + (++i));    
  }
}

var f = fn(); 
f(10); // 21
f(20); // 32
fn()(10); // 21
fn()(20);  // 31

This關(guān)鍵字

在JS中主要研究都是函數(shù)中的this

JS中的this代表的是當(dāng)前行為執(zhí)行的主體(方法,函數(shù),事件...)
JS中的上下文(context)代表的是當(dāng)前行為執(zhí)行的環(huán)境(區(qū)域)
例如: 小明在沙縣小吃吃蛋炒飯。 this->小明 ,context->沙縣小吃
小明可以在沙縣小吃吃,也可以在其他地方吃。上下文環(huán)境可以變化。而吃的主體小明是不變的。
thiscontext是沒有必然聯(lián)系。

this是誰,和函數(shù)在哪里定義,在哪里執(zhí)行都沒有任何的關(guān)系。和執(zhí)行主體有關(guān)系

如何判斷執(zhí)行主體?

函數(shù)執(zhí)行,首先看函數(shù)名前面是否有.,有的話,.前面是誰,this就是誰;沒有的話this就是window

function fn() {
  console.log(this);
}
var obj = {
  fn: fn
}
fn(); // fn中的this, window
obj.fn(); // fn中的this, obj

function sum() {
  fn(); // fn中的this,window
};
sum();

var o = {
  sum: function() {
    fn(); // fn中的this,window
  }
}
o.sum();

自執(zhí)行函數(shù)中的this,指代window

給元素的某一事件綁定方法,當(dāng)事件觸發(fā)的時候,執(zhí)行對應(yīng)的方法,方法中的this是當(dāng)前的元素.

document.getElementById("div1").onclick = function() {
  console.log(this); // 當(dāng)前DOM對象
}
var num = 20;
var obj = {
  num: 30,
  fn: (function(num) {
    this.num *= 3;
    num += 15;
    return function() {
      this.num *= 4; 
      num += 20;
      console.log(num);
    }   
  })(num)
};

var fn = obj.fn; 
fn(); // window,// 60 * 4 // 35 += 20 // 55
obj.fn(); // 75
console.log(window.num, obj.num); // 240, 120

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/88261.html

相關(guān)文章

  • ECMA 規(guī)范解讀 Javascript 可執(zhí)行上下文概念

    摘要:不包括作為其嵌套函數(shù)的被解析的源代碼。作用域鏈當(dāng)代碼在一個環(huán)境中執(zhí)行時,會創(chuàng)建變量對象的一個作用域鏈。棧結(jié)構(gòu)最頂層的執(zhí)行環(huán)境稱為當(dāng)前運行的執(zhí)行環(huán)境,最底層是全局執(zhí)行環(huán)境。無限制函數(shù)上下文?;蛘邟伋霎惓M顺鲆粋€執(zhí)行環(huán)境。 前言 其實規(guī)范這東西不是給人看的,它更多的是給語言實現(xiàn)者提供參考。但是當(dāng)碰到問題找不到答案時,規(guī)范往往能提供想要的答案 。偶爾讀一下能夠帶來很大的啟發(fā)和思考,如果只讀一...

    daryl 評論0 收藏0
  • 深入JavaScript(一)this & Prototype

    摘要:然而事實上并不是。函數(shù)本身也是一個對象,但是給這個對象添加屬性并不能影響。一圖勝千言作者給出的解決方案,沒有麻煩的,沒有虛偽的,沒有混淆視線的,原型鏈連接不再赤裸裸。所以是這樣的一個函數(shù)以為構(gòu)造函數(shù),為原型。 注意:本文章是個人《You Don’t Know JS》的讀書筆記。在看backbone源碼的時候看到這么一小段,看上去很小,其實忽略了也沒有太大理解的問題。但是不知道為什么,我...

    The question 評論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統(tǒng)的類繼承還要強大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評論0 收藏0
  • JavaScript進(jìn)階之函數(shù)和對象知識點詳解

      在過往學(xué)習(xí)的JavaScript都是在基礎(chǔ),現(xiàn)在為大家介紹更為深入的JavaScript知識。  JavaScript函數(shù)  JavaScript函數(shù)和Java函數(shù)是有一部分相似的,所以學(xué)習(xí)起來也會相對簡單  基本構(gòu)造  1.直接構(gòu)造  //function代表函數(shù)標(biāo)志,name為函數(shù)名稱,參數(shù)可有可無   functionname(參數(shù)){   //...   return;   }  2....

    3403771864 評論0 收藏0
  • FE.ES-理解ECMA Javascript的this

    摘要:捕獲所有參數(shù)綁定當(dāng)一個函數(shù)用作構(gòu)造函數(shù)時使用關(guān)鍵字,它的被綁定到正在構(gòu)造的新對象。使用來調(diào)用函數(shù),或者說發(fā)生構(gòu)造函數(shù)調(diào)用時,會自動執(zhí)行下面的操作你不知道的創(chuàng)建或者說構(gòu)造一個全新的對象。在箭頭函數(shù)中,與封閉詞法上下文的保持一致。 this 實際上是在函數(shù)被調(diào)用時發(fā)生的綁定,它指向什么完全取決于函數(shù)的調(diào)用位置(也就是函數(shù)的調(diào)用方法)。 四條規(guī)則:(你不知道的JS) 1. 默認(rèn)綁定 func...

    Meils 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<