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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [toc] ## previously JS中的對象和函數匯總 >對象數據類型的值 >- `{}`普通對象 > - `[]` 數組 > - `/^$/` 正則 > - `Math` 數學函數 > - 一般類的實例都是對象數據類型 > - 函數的`prototype`屬性 > > - 實例的`__proto__`屬性 > - ... > > 函數數據類型值 > - 普通函數 > - 所有的類(內置類和自定義類) > - ... ``` typeof Object === 'function' typeof String === 'function' typeof Fn === 'function' ``` ## 原型(xx.prototype) >1、 所有的函數都天生自帶一個屬性:prototype(原型),它是一個對象數據類型的值,在這個對象中存儲了為其類的實例提供的公共屬性和方法。 > >2、 prototype這個對象,瀏覽器會默認為其開辟一個堆內存,在這個堆內存中天生自帶一個屬性:constructor(構造函數),這個屬性存儲的值就是當前函數本身。 > >3、 每一個類的實例(每一個對象)都天生自帶一個屬性:`__proto__`,屬性值是當前對象所屬類的原型(prototype)。 > >4、 每一個類的原型的`__proto__`都指向`Object`類的原型 ``` function Fn(name,age){ } ``` ``` function Fn(name,age){ this.name = name; this.age = age; this.say = function(){ console.log(`my name is ${this.name}!i am ${this.age}years old!`) } } Fn.prototype.say = function(){ console.log('hello world!'); } Fn.prototype.eat = function(){ console.log('i love food!'); } var f1 = new Fn('ahhh',11); var f1 = new Fn('ahhh2',70); ``` ![](https://box.kancloud.cn/e42c605c3ee662ce123251fc8b9a7d62_1535x581.png) ## 原型鏈(`__proto__`) 也是一種設計模式,原型鏈模式 若一個對象下的屬性或方法在自己身上找不到,會順著`__proto__`網上找,`__proto__`指向的是另外一個對象,這個對象中有的方法和屬性,都能傳遞給下層的對象 ![](https://box.kancloud.cn/4a53ffe0b3529f4343aca6ed6b989d2a_1771x566.png) ### this問題 > 關于原型鏈中提供的私有(公有)方法中的THIS指向問題 > 1、 看點前面是誰,THIS就是誰 > f1.say():this->f1 > f1.__proto__.say():this->f1.__proto__ > Fn.prototype.say():this->Fn.prototype > ... >2、 把需要執行方法中的THIS進行替換 >3、 替換完成后,如果想要知道結果,值需按照原型鏈的查找機制去查找即可 ### 向原型上批量增加屬性和方法 ``` function Fn(name,age){ this.name = name; this.age = age; } Fn.prototype.aa = function(){ }; Fn.prototype.bb = function(){ }; ... var f = new Fn('xxx',28); ``` #### 設置別名 ``` //設置別名 var pro = Fn.prototype; //=>指向同一個堆內存 ``` #### 重新構造原型(內置類不支持,內置類想添加方法和屬性只能一個個加) ``` Fn.prototype = { //=>讓原型指向自己開辟的堆內存有一個問題,自己開辟的堆內存中沒有constructor這個屬性,所以實例在調取constructor的時候找到的是Object,這樣不好,此時我們應該重新設置以下constructor,保證機制的完整性 constructor:Fn ,aa:function(){ } ,bb:function(){ } }; ``` #### 基于內置類的原型擴展方法 >1、 我們新增加的方法最好設置一個前綴,防止我們新增加的方法和內置的方法沖突,把內置的方法替換掉 >2、 返回的結果依然是當前類的實例,這樣就可以繼續調取當且類的其它方法操作了。 ``` //其中obj只是一個key的清單 function distinct(ary){ var obj = {}; for(var i=0;i<ary.length;++i){ var item = ary[i]; if(typeof obj[item]!=='undefined'){ ary[i] = ary[ary.length-1]; ary.length--; i--; continue; } obj[item] = item; } } //內置方法的方法是一個具名函數 Array.prototype.myDistinct = function myDistinct(){ //=>this:ary當期那要處理的數組 var obj = {}; for(var i=0;i<this.length;++i){ var item = this[i]; if(typeof obj[item]!=='undefined'){ this[i] = this[this.length-1]; this.length--; i--; continue; } obj[item] = item; } obj = null; return this; } ``` ![](https://box.kancloud.cn/5c822c66c8a9dc3981b93b3b780279b1_212x85.png) ## 習題 實現(3).plus(2).minus(1) =>4 >[warning] **注意:** `()`能將一個數值包裝成一個真正的數字類型的實例。(可以使用實例中的方法),其次數值類的this就是數字本身。 ``` Number.prototype.plus = function plus(){ var value = Number(arguments[0])||0; return this+arguments[0]; } Number.prototype.minus = function minus(){ var value = Number(arguments[0])||0; return this-arguments[0]; } console.log((3).plus(2).minus(1)) ``` ## 函數 ### previously Function -> 函數類 類都天生自帶一個屬性`prototype` 它的原型上有`call`、`apply`、`bind`等方法 它的原型的`__proto__`也指向`Object.prototype`。 所有函數(包括類)都是`Function`的實例 **所有函數都是`Function`這個類的實例,So所有函數都能作為一個實例存在,也就是一個對象。** ![](https://box.kancloud.cn/b6c62e344d388ab313d18894c3f526d3_1683x773.png) `Object`類的`__proto__`指向`Function`,而`Function`的`prototype`指向的是`Object.prototype`。 并且`Function`的`__proto__`指向自己的prototype ![](https://box.kancloud.cn/d9cb9ac84c9c68097f0999a779aad9bc_313x65.png) `Function`的原型是**函數數據類型**的值,但相關操作和之前的一模一樣。->anonymous/Empty ### 三種角色 >函數本也會有一些自己的屬性: >`legnth`:0 形參的個數 >`name`:“Fn”函數名 >`prototype`: 類的原型,在原型上定義的方法都是當前Fn這個類實例的公有方法 >`__proto__`:把函數當做一個普通的對象,指向Function這個類的原型 >函數在整個JS中是最復雜也是最重要ode只是 >1、 一個函數存在多面性 >->它本身就是一個普通的函數,執行的時候形成私有的作用域(閉包),形參賦值,預解釋,代碼執行,執行完成后棧內存銷毀/不銷毀 >->“類”:它有自己的實例,也有一個叫做prototype屬性是自己的原型,它的實例都指向自己的原型 >->“普通對象”:和var obj={}中的obj一樣,也是一個對象,它作為對象可以有一些自己私有的屬性,也可以通過`__proto__`找到Function.prototype 三種角色之間沒有必然聯系 ``` function Fn(){ var num = 500; this.x = 100; } Fn.prototype.geX = function(){ console.log(this.x); } Fn.aaa = 1000; //類 var f= new Fn; f.num -> undefined f.aaa -> undefined; //普通函數 var res = Fn(); //->Fn中的this是window res = undefined; //普通對象 Fn.aaa = 1000; ``` ### call ``` //改變this關鍵字 //Function.prototype.call = function(){} var obj = {name:'ahhh'} function fn(){ console.log(this); } fn(); // obj.fn(); fn.call(obj) //->首先我們讓原型上的call方法執行,在執行call方法的時候,我們讓fn方法中的this變為第一個參數的值,即obj;然后再把fn這個函數執行 Function.prototype.myCall = function(context){ //->myCall方法中的this就是當前我要操作和改變其this關鍵字的那個函數名 //->1、讓fn中的this關鍵字變為context的值 //->讓this這個函數中的"this關鍵字"變為context var that = eval(this.toString().replace("this",context)); //->2、讓fn方法再執行 that(); }; fn.myCall(obj); ``` ``` function fn1(){console.log(1)}; function fn2(){console.log(2)}; fn1.call(fn2); ``` ``` fn1.call.call(fn2); ``` 首先fn1通過原型鏈找到callFunction.prototype上的call方法,然后再讓call方法通過原型再找到Function原型上的call(因為call本身的值也是一個函數,所以同樣可以找到Function.prototype),在第二次再找到call的時候讓方法執行,方法中的this是fn1.call,首先讓這個方法中的this變為fn2,然后再讓fn1.call執行 ``` var obj = {name:'ahhh'} function fn(num1,num2){ console.log(num1+num2); console.log(this); } fn.call(100,200); fn.call(obj,100,200); fn.call(); //this->window fn.call(null);//this->window fn.call(undefined);//this->window ``` 嚴格模式下this指向 ``` "use strict";//=>告訴當前瀏覽器接下來的JS代碼將按照嚴格模式進行編寫 fn.call(); //this->undefined fn.call(null);//this->null fn.call(undefined);//this->undefined ``` ### apply apply和方法的作用是一模一樣的,都是用來改變this關鍵字并且把方法執行;而且在嚴格模式下和非嚴格模式下對于第一個參數是null/undefined這種情況的規律也是一樣的 ``` fn.call(obj,100,200); fn.apply(obj,[100,200]); ``` call在給fn傳遞參數的時候,是一個個傳遞值的,而apply不是一個個傳的,而是把要給fn傳遞的參數值統一的放在一個數組中進行操作的->但是也相當于一個個的給fn的形參賦值 ### bind 這個方法在IE6~8不兼容 此方法和call/apply類似,都是用來改變this關鍵字的 ``` fn.call(obj,1,2); //->改變this和執行fn函數是都一起完成了 //->預處理:事先把fn的this改變為我們想要的結果,并且把對應的參數值也準備好,以后要用到了,直接執行即可 var tempFn = fn.bind(obj,1,2); //->只是改變了fn中的this為obj,并且給fn傳遞了兩個參數1、2,但此時并沒有把fn這個函數執行,執行bind會有一個返回值,這個返回值tempFn就是我們把fn的this改變后的那個結果 tempFn(); ```
                  <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>

                              哎呀哎呀视频在线观看