<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 目標 無具體目標 ## [](https://github.com/alsotang/node-lessons/tree/master/lesson11#知識點)知識點 1. 理解 js 中 var 的作用域 2. 了解閉包的概念 3. 理解 this 的指向 ## [](https://github.com/alsotang/node-lessons/tree/master/lesson11#課程內容)課程內容 ### [](https://github.com/alsotang/node-lessons/tree/master/lesson11#var-作用域)var 作用域 先來看個簡單的例子: ~~~ var parent = function () { var name = "parent_name"; var age = 13; var child = function () { var name = "child_name"; var childAge = 0.3; // => child_name 13 0.3 console.log(name, age, childAge); }; child(); // will throw Error // ReferenceError: childAge is not defined console.log(name, age, childAge); }; parent(); ~~~ 直覺地,內部函數可以訪問外部函數的變量,外部不能訪問內部函數的變量。上面的例子中內部函數 child 可以訪問變量 age,而外部函數 parent 不可以訪問 child 中的變量 childAge,因此會拋出沒有定義變量的異常。 有個重要的事,如果忘記var,那么變量就被聲明為全局變量了。 ~~~ function foo() { value = "hello"; } foo(); console.log(value); // 輸出hello console.log(global.value) // 輸出hello ~~~ 這個例子可以很正常的輸出?`hello`,是因為?`value`?變量在定義時,沒有使用?`var`?關鍵詞,所以被定義成了全局變量。在 Node 中,全局變量會被定義在?`global`?對象下;在瀏覽器中,全局變量會被定義在?`window`?對象下。 如果你確實要定義一個全局變量的話,請顯示地定義在?`global`?或者?`window`?對象上。 這類不小心定義全局變量的問題可以被 jshint 檢測出來,如果你使用 sublime 編輯器的話,記得裝一個?`SublimeLinter`?插件,這是插件支持多語言的語法錯誤檢測,js 的檢測是原生支持的。 JavaScript 中,變量的局部作用域是函數級別的。不同于 C 語言,在 C 語言中,作用域是塊級別的。 JavaScript 中沒有塊級作用域。 js 中,函數中聲明的變量在整個函數中都有定義。比如如下代碼段,變量 i 和 value 雖然是在 for 循環代碼塊中被定義,但在代碼塊外仍可以訪問 i 和 value。 ~~~ function foo() { for (var i = 0; i < 10; i++) { var value = "hello world"; } console.log(i); //輸出10 console.log(value);//輸出hello world } foo(); ~~~ 所以有種說法是:應該提前聲明函數中需要用到的變量,即,在函數體的頂部聲明可能用到的變量,這樣就可以避免出現一些奇奇怪怪怪的 bug。 但我個人不喜歡遵守這一點,一般都是現用現聲明的。這類錯誤的檢測交給 jshint 來做就好了。 ### [](https://github.com/alsotang/node-lessons/tree/master/lesson11#閉包)閉包 閉包這個概念,在函數式編程里很常見,簡單的說,就是使內部函數可以訪問定義在外部函數中的變量。 假如我們要實現一系列的函數:add10,add20,它們的定義是?`int add10(int n)`。 為此我們構造了一個名為 adder 的構造器,如下: ~~~ var adder = function (x) { var base = x; return function (n) { return n + base; }; }; var add10 = adder(10); console.log(add10(5)); var add20 = adder(20); console.log(add20(5)); ~~~ 每次調用 adder 時,adder 都會返回一個函數給我們。我們傳給 adder 的值,會保存在一個名為 base 的變量中。由于返回的函數在其中引用了 base 的值,于是 base 的引用計數被 +1。當返回函數不被垃圾回收時,則 base 也會一直存在。 我暫時想不出什么實用的例子來,如果想深入理解這塊,可以看看這篇?[http://coolshell.cn/articles/6731.html](http://coolshell.cn/articles/6731.html) #### [](https://github.com/alsotang/node-lessons/tree/master/lesson11#閉包的一個坑)閉包的一個坑 ~~~ for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 5); } ~~~ 上面這個代碼塊會打印五個?`5`?出來,而我們預想的結果是打印 1 2 3 4 5。 之所以會這樣,是因為 setTimeout 中的 i 是對外層 i 的引用。當 setTimeout 的代碼被解釋的時候,運行時只是記錄了 i 的引用,而不是值。而當 setTimeout 被觸發時,五個 setTimeout 中的 i 同時被取值,由于它們都指向了外層的同一個 i,而那個 i 的值在迭代完成時為 5,所以打印了五次?`5`。 為了得到我們預想的結果,我們可以把 i 賦值成一個局部的變量,從而擺脫外層迭代的影響。 ~~~ for (var i = 0; i < 5; i++) { (function (idx) { setTimeout(function () { console.log(idx); }, 5); })(i); } ~~~ ### [](https://github.com/alsotang/node-lessons/tree/master/lesson11#this)this 在函數執行時,this 總是指向調用該函數的對象。要判斷 this 的指向,其實就是判斷 this 所在的函數屬于誰。 在《javaScript語言精粹》這本書中,把 this 出現的場景分為四類,簡單的說就是: * 有對象就指向調用對象 * 沒調用對象就指向全局對象 * 用new構造就指向新對象 * 通過 apply 或 call 或 bind 來改變 this 的所指。 1)函數有所屬對象時:指向所屬對象 函數有所屬對象時,通常通過?`.`?表達式調用,這時?`this`?自然指向所屬對象。比如下面的例子: ~~~ var myObject = {value: 100}; myObject.getValue = function () { console.log(this.value); // 輸出 100 // 輸出 { value: 100, getValue: [Function] }, // 其實就是 myObject 對象本身 console.log(this); return this.value; }; console.log(myObject.getValue()); // => 100 ~~~ `getValue()`?屬于對象?`myObject`,并由?`myOjbect`?進行?`.`?調用,因此?`this`?指向對象?`myObject`。 2) 函數沒有所屬對象:指向全局對象 ~~~ var myObject = {value: 100}; myObject.getValue = function () { var foo = function () { console.log(this.value) // => undefined console.log(this);// 輸出全局對象 global }; foo(); return this.value; }; console.log(myObject.getValue()); // => 100 ~~~ 在上述代碼塊中,`foo`?函數雖然定義在?`getValue`?的函數體內,但實際上它既不屬于?`getValue`?也不屬于`myObject`。`foo`?并沒有被綁定在任何對象上,所以當調用時,它的?`this`?指針指向了全局對象?`global`。 據說這是個設計錯誤。 3)構造器中的 this:指向新對象 js 中,我們通過?`new`?關鍵詞來調用構造函數,此時 this 會綁定在該新對象上。 ~~~ var SomeClass = function(){ this.value = 100; } var myCreate = new SomeClass(); console.log(myCreate.value); // 輸出100 ~~~ 順便說一句,在 js 中,構造函數、普通函數、對象方法、閉包,這四者沒有明確界線。界線都在人的心中。 4) apply 和 call 調用以及 bind 綁定:指向綁定的對象 apply() 方法接受兩個參數第一個是函數運行的作用域,另外一個是一個參數數組(arguments)。 call() 方法第一個參數的意義與 apply() 方法相同,只是其他的參數需要一個個列舉出來。 簡單來說,call 的方式更接近我們平時調用函數,而 apply 需要我們傳遞 Array 形式的數組給它。它們是可以互相轉換的。 ~~~ var myObject = {value: 100}; var foo = function(){ console.log(this); }; foo(); // 全局變量 global foo.apply(myObject); // { value: 100 } foo.call(myObject); // { value: 100 } var newFoo = foo.bind(myObject); newFoo(); // { value: 100 } ~~~ 完。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看