<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 功能強大 支持多語言、二開方便! 廣告
                # 方法 在一個對象中綁定函數,稱為這個對象的方法。 在JavaScript中,對象的定義是這樣的: ~~~js var xiaoming = { name: '小明', birth: 1990 }; ~~~ 但是,如果我們給`xiaoming`綁定一個函數,就可以做更多的事情。比如,寫個`age()`方法,返回`xiaoming`的年齡: ~~~js var xiaoming = { name: '小明', birth: 1990, age: function () { var y = new Date().getFullYear(); return y - this.birth; } }; xiaoming.age; // function xiaoming.age() xiaoming.age(); // 今年調用是25,明年調用就變成26了 ~~~ 綁定到對象上的函數稱為方法,和普通函數也沒啥區別,但是它在內部使用了一個`this`關鍵字,這個東東是什么? 在一個方法內部,`this`是一個特殊變量,它始終指向當前對象,也就是`xiaoming`這個變量。所以,`this.birth`可以拿到`xiaoming`的`birth`屬性。 讓我們拆開寫: ~~~ function getAge() { var y = new Date().getFullYear(); return y - this.birth; } var xiaoming = { name: '小明', birth: 1990, age: getAge }; xiaoming.age(); // 25, 正常結果 getAge(); // NaN ~~~ 單獨調用函數`getAge()`怎么返回了`NaN`?*請注意*,我們已經進入到了JavaScript的一個大坑里。 JavaScript的函數內部如果調用了`this`,那么這個`this`到底指向誰? 答案是,視情況而定! 如果以對象的方法形式調用,比如`xiaoming.age()`,該函數的`this`指向被調用的對象,也就是`xiaoming`,這是符合我們預期的。 如果單獨調用函數,比如`getAge()`,此時,該函數的`this`指向全局對象,也就是`window`。 坑爹啊! 更坑爹的是,如果這么寫: ~~~ var fn = xiaoming.age; // 先拿到xiaoming的age函數 fn(); // NaN ~~~ 也是不行的!要保證`this`指向正確,必須用`obj.xxx()`的形式調用! 由于這是一個巨大的設計錯誤,要想糾正可沒那么簡單。ECMA決定,在strict模式下讓函數的`this`指向`undefined`,因此,在strict模式下,你會得到一個錯誤: ~~~ 'use strict'; var xiaoming = { name: '小明', birth: 1990, age: function () { var y = new Date().getFullYear(); return y - this.birth; } }; var fn = xiaoming.age; fn(); // Uncaught TypeError: Cannot read property 'birth' of undefined ~~~ 這個決定只是讓錯誤及時暴露出來,并沒有解決`this`應該指向的正確位置。 有些時候,喜歡重構的你把方法重構了一下: ~~~ 'use strict'; var xiaoming = { name: '小明', birth: 1990, age: function () { function getAgeFromBirth() { var y = new Date().getFullYear(); return y - this.birth; } return getAgeFromBirth(); } }; xiaoming.age(); // Uncaught TypeError: Cannot read property 'birth' of undefined ~~~ 結果又報錯了!原因是`this`指針只在`age`方法的函數內指向`xiaoming`,在函數內部定義的函數,`this`又指向`undefined`了!(在非strict模式下,它重新指向全局對象`window`!) 修復的辦法也不是沒有,我們用一個`that`變量首先捕獲`this`: ~~~ 'use strict'; var xiaoming = { name: '小明', birth: 1990, age: function () { var that = this; // 在方法內部一開始就捕獲this function getAgeFromBirth() { var y = new Date().getFullYear(); return y - that.birth; // 用that而不是this } return getAgeFromBirth(); } }; xiaoming.age(); // 25 ~~~ 用`var that = this;`,你就可以放心地在方法內部定義其他函數,而不是把所有語句都堆到一個方法中。 ## apply 雖然在一個獨立的函數調用中,根據是否是strict模式,`this`指向`undefined`或`window`,不過,我們還是可以控制`this`的指向的! 要指定函數的`this`指向哪個對象,可以用函數本身的`apply`方法,它接收兩個參數,第一個參數就是需要綁定的`this`變量,第二個參數是`Array`,表示函數本身的參數。 用`apply`修復`getAge()`調用: ~~~ function getAge() { var y = new Date().getFullYear(); return y - this.birth; } var xiaoming = { name: '小明', birth: 1990, age: getAge }; xiaoming.age(); // 25 getAge.apply(xiaoming, []); // 25, this指向xiaoming, 參數為空 ~~~ 另一個與`apply()`類似的方法是`call()`,唯一區別是: * `apply()`把參數打包成`Array`再傳入; * `call()`把參數按順序傳入。 比如調用`Math.max(3, 5, 4)`,分別用`apply()`和`call()`實現如下: ~~~ Math.max.apply(null, [3, 5, 4]); // 5 Math.max.call(null, 3, 5, 4); // 5 ~~~ 對普通函數調用,我們通常把`this`綁定為`null`。 ## 裝飾器 利用`apply()`,我們還可以動態改變函數的行為。 JavaScript的所有對象都是動態的,即使內置的函數,我們也可以重新指向新的函數。 現在假定我們想統計一下代碼一共調用了多少次`parseInt()`,可以把所有的調用都找出來,然后手動加上`count += 1`,不過這樣做太傻了。最佳方案是用我們自己的函數替換掉默認的`parseInt()`: ~~~ var count = 0; var oldParseInt = parseInt; // 保存原函數 window.parseInt = function () { count += 1; return oldParseInt.apply(null, arguments); // 調用原函數 }; // 測試: parseInt('10'); parseInt('20'); parseInt('30'); count; // 3 ~~~
                  <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>

                              哎呀哎呀视频在线观看