<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                最近閱讀了《JavaScript設計模式與開發實踐》(2015年度最佳推薦),收獲頗多,自己對設計模式有了全新的了解和認識。在項目實踐中也用到了一些,感覺很不錯。 設計模式應遵守的原則: (1)最少知識原則:一個軟件實體應當盡可能少地與其他實體發生相互作用(把對象劃分成較小的粒度,以便提高復用性) (2)開放-封閉原則:軟件實體(類、模塊、函數)等應該是可以擴展的,但是不可修改。 ### 一、原型模式 JavaScript基于原型的委托機制實現對象與對象之間的繼承。 當對象無法響應某個請求時,會把該請求委托給它自己的原型。 構造器有原型,實例對象沒有原型,有一個名為proto的屬性,其默認指向它的構造器的原型對象,即{constructor}.prototype。 **示例一:** ~~~ var obj = {name: "ligang"}; var A = function() {}; A.prototype = obj; var a = new A(); console.log(a.name); // ligang ~~~ (1)遍歷對象a中所有屬性,未找到name屬性 (2)查找name屬性的請求被委托給對象a的對象構造器的原型,它被a.**proto**記錄著并且指向A.prototype,而其被設置為對象obj (3)在對象obj中找到name屬性,并返回。 **示例二:** ~~~ var obj = {name: "ligang"}; var A = function(name) { this.name = name; }; A.prototype = obj; var a = new A(); console.log(a.name); // undefined ~~~ (1)首選遍歷對象a中的所有屬性,存在name屬性,但未賦值 **示例三:** ~~~ var obj = {name: "ligang"}; var A = function() {}; A.prototype = obj; var B = function() {}; B.prototype = new A(); var b = new B(); console.log(b.name); // ligang ~~~ 查找順序: b對象 –> b.proto(即:B.prototype) –> new A()對象 –> B.prototype –> obj ### 二、this #### 1. 詞法作用域 首先明確JavaScript只具備詞法作用域(書寫代碼時函數聲明的位置來決定),不具備動態作用域。通過下述示例說明。 備注:詞法作用域詳見:[《JavaScript詞法作用域(你不知道的JavaScript)》](http://blog.csdn.net/ligang2585116/article/details/46367565) **示例一:** ~~~ function foo() { console.log(a); } function bar() { var a = 1; foo(); } bar(); // ReferenceError ~~~ **示例二:** ~~~ function foo() { console.log(this.a); // this指向window } function bar() { var a = 1; foo(); } bar(); // undefined ~~~ **示例三:** ~~~ function foo() { console.log(this.a); } function bar() { this.a = 1; foo(); } bar(); // 1 ~~~ 如果JavaScript存在動態作用域,示例一的結果應該為1。 #### 2. this 下面補充幾點this注意事項 備注:關于this詳見:[《JavaScript中的this(你不知道的JavaScript)》](http://blog.csdn.net/ligang2585116/article/details/47059289) (1)this指向(構造器調用) **示例一:** ~~~ var MyClass = function() { this.age = 25; this.name = "ligang"; }; var obj = new MyClass(); console.log("姓名:" + obj.name + " 年齡:" + obj.age); // 姓名:ligang 年齡:25 ~~~ **示例二:** ~~~ var MyClass = function() { this.age = 25; this.name = "ligang"; return { name: "camile" }; }; var obj = new MyClass(); console.log("姓名:" + obj.name + " 年齡:" + obj.age); // 姓名:camile 年齡:undefined ~~~ **注意:**如果構造器顯式地返回一個object類型的對象,那么此次運算最終返回這個對象,而不是我們之前期待的this。 #### 3. 指定函數內部this指向 call、apply、Function.prototype.bind 其中Function.prototype.bind部分瀏覽器不兼容,兼容性請查看[http://caniuse.com/](http://caniuse.com/) 模擬實現Function.prototype.bind: ~~~ Function.prototype.bind = function() { var self = this, context = [].shift.call(arguments), args = [].slice.call(arguments); return function() { return self.apply(context, [].concat.call(args, [].slice.call(arguments))); }; }; // 測試 var obj = { name: "ligang" }; var func = function(a, b, c) { console.log(this.name); console.log([a, b, c]) }.bind(obj, 1, 2); func(3); ~~~ ### 三、閉包和高階函數 #### 1. 閉包 對象以方法的形式包含了過程,而閉包則是在過程中一環境的形式包含了數據。 **示例:緩存機制** ~~~ var mult = (function() { var cache = {}; return function() { var args = Array.prototype.join.call(arguments, ","); if(args in cache) { return cache[args]; } var a = 1; for(var i = 0, l = arguments.length; i < l; i++) { a = a * arguments[i]; } return cache[args] = a; } })(); console.log(mult(1, 2, 3)); console.log(mult(1, 2, 3)); // 再次計算,直接從緩存中取 ~~~ **注意:**閉包容易導致循環引用,從而導致內存溢出。可以通過把這些變量置為null,回收這些變量。 #### 2. 高階函數 高階函數:函數作為參數傳遞;函數作為返回值輸出。 (1)回調函數 ~~~ function fun(callback) { console.log(1); if(typeof callback === 'function'){ setTimeout(function() { callback(); }); } } fun(function(){console.log(2);}); ~~~ (2)判斷數據類型 ~~~ var isType = function(type) { return function(obj) { return Object.prototype.toString.call(obj) === '[object' + type + ']'; } }; var isArray = isType("Array"); var isNumber = isType("Number"); isArray([]); isNumber("123"); ~~~ (3)單例 ~~~ var getSingle = function(fn) { var result; return function() { return result || (result = fn.apply(this, arguments)); }; }; function testSingle(){} getSingle(testSingle)() === getSingle(testSingle)(); // true ~~~ 轉載請標明出處:[http://blog.csdn.net/ligang2585116](http://blog.csdn.net/ligang2585116)!
                  <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>

                              哎呀哎呀视频在线观看