JavaScript閉包和範圍執行個體詳解,javascript詳解

來源:互聯網
上載者:User

JavaScript閉包和範圍執行個體詳解,javascript詳解

本文執行個體分析了JavaScript閉包和範圍。分享給大家供大家參考,具體如下:

1.

if (!("a" in window)) {  var a = 1;}alert(a);

【分析】代碼含義:如果window不包含屬性a,就聲明一個變數a並賦值為1

①JS引擎會先掃描所有的變數聲明

②所有的全域變數都是window的屬性

③變數聲明和賦值一起用時,Js引擎會自動將它分成兩部分:變數聲明提前,變數賦值沒有(不將賦值提前是因為他有可能影響代碼執行出不可預期的結果)

所以代碼執行順序等價於

var a;if(!("a" in window)) {  a = 1;}alert(a);

解析:聲明變數a,判斷a是否存在,不存在就賦值為1,而這裡a永遠在window裡存在,指派陳述式永不執行,所以結果是undefined

2.

if (!("a" in window)) {  function a() { window.a = 1; }}alert(a);

【分析】

①函式宣告也會提前並且會覆蓋變數聲明,但不會覆蓋變數賦值,如下例子

function value(){  return 1;}var value;alert(typeof value);  //"function"

function value(){  return 1;}var value = 1;alert(typeof value);  //"number"

②所有全域變數都是window屬性,語句var a=1;等同於window.a=1;

所以代碼執行順序等價於

function a() {window.a = 1;}if(!("a" in window)) {  function a() { var a = 1; }}alert(a);

輸出結果:function a() {window.a = 1; }

變形:

if ("a" in window) {  function a() { window.a = 1; }}alert(a);

輸出結果:a is not defined

函式宣告裡的變數定義,要到執行函數時才會定義,並不會在先行編譯階段就聲明變數

3.

if (!("a" in window)) {  var a = function () { window.a = 1; }}alert(a);

【分析】

①函式宣告和函數運算式區別

函式宣告:

function functionName(arg1, arg2){  //函數體}

函數運算式(相當於變數賦值):

var functionName = function(arg1, arg2){  //函數體};

所以代碼執行順序等價於

var a;if (!("a" in window)) {  a = function () { window.a = 1; }}alert(a);

結果和第一題一樣,undefined

4.

var a = 1,  b = function a(x) {    x && a(--x);  };alert(a);

【分析】

①進入執行內容的階段

VO(global) = {  a: undefined,  b: undefined}

這階段的順序:函數的形參->函式宣告->變數聲明

②執行代碼階段

VO(global) = {  x: undefined,  a: 1}

③定義變數b,賦值名字為a的函數(這個a只能在函數體內使用)

④如果x是任何true值(這這裡應該是非0)則執行後面的語句

⑤換成更能理解的代碼

var a = 1,  b = function(x) {    x && b(--x);  };alert(a);

結果為1

5.

function b(x, y, a) {  arguments[2] = 10;  alert(a);}b(1, 2, 3);

【分析】沒有痛點,輸出10,如果改成

function b(x, y, a) {  arguments[2] = 10;  alert(a);}b(1, 2);

則輸出undefined,因為沒有傳遞a的值

6.

function a() {  alert(this);}a.call(null);

【分析】

①a.call(b)表示a對象的方法應用到b對象上(即b對象繼承了a對象),根據規定,第一個參數是null或undefined,call方法就把全域對象(也就是window)作為this的值

②call()和apply()的區別:功能一樣,第二個參數形式不一樣,call傳遞多個參數,任意形式,apply第二個參數必須是數組形式,如

a.call(b,2,3); ==>  a.apply(b,[2,3]);

輸出結果:[object Window]

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.