面向对象第6天

     今天学习效率还是不高,this已经把我弄晕了,面向对象果然很难,重点掌握函数的四种调用模式。

一、闭包科里化应用

     案例:小新闻    

           function update(target) {
              return function(data) {
                   $(target).html("<h2>"+ data.title + "</h2><p>" + data.details + "</p>");
                 };
           }

          function refresh(url, callback) {
              $.ajax({
                  url: url,
                  type: "POST",
                  dataType: 'json',
                  success: callback,
                  fail: function(er) {
                          console.log(er);
                      }
               });
            }

          refresh("CBAData.json", update("#CBA"));
          refresh("NBAData.json", update("#NBA"));
          refresh("WCBAData.json", update("#WCBA"));

 二、闭包的优缺点

     1.缺点:

         常驻内存,增大内存的开销,使用不当就会造成内存泄漏。

     2. 优点:

       (1)实现缓存

       (2)实现封装

       (3)避免污染全局对象

       (4)处理逻辑的连续性

  三、应用

       参数复用;延迟计算/执行;提前返回

  四、作用域链

     1.作用:

           加强变量搜索原则的记忆

     2. 绘制作用域链的步骤:

       (1)全局作用域 为 0 级链。将在当前作用域上的变量、对象等数据,绘制在该链上。

       (2)函数可以限定作用域,在绘制过程中,只要遇到函数,就在此基础上扩展一条新俩链,级别为 当前级别 + 1;

       (3)重复2步骤,直到所有函数都扩展出了新链为止。

    3. 注意点:

      (1)在变量搜索的时候,如果访问的是全局变量,那么会搜索整个作用域链。性能会降低。在实际开发时,可以将常用的全局对象传入局部变量内。

      (2)在同级链上的变量,互相不能访问。

  五、函数的四种调用模式

     1. 作用:

         确定this指向的。

    2. 四种模式介绍 

      (1)普通函数执行模式:声明一个函数后,直接通过函数的名字调用

          function foo(){

           console.log(this);      this ->window

         }

         foo();

      (2)构造函数模式:通过new操作符创建一个对象,此时该函数的执行模式为构造函数模式

         function fn(){

           console.log(this);        this->构造函数创建出来的对象,即f

        }

        var f=new fn;

      (3)方法调用模式:通过对象来调用

          var obj={

             say:function(){

                 console.log(this);     this->方法的调用者

              }              

          };

           obj.say();

      (4)上下文模式(call/apply模式)  作用:动态改变this的指向

         function print(){

            console.log(this.name);          this->call/apply方法的第一个参数

       }

        var obj={name:'tom'};

        print.call(obj);

     3. call和apply的区别:

      (1)fn.call(thisObj, arg1, arg2, arg3, ...argN);

             thisObj         在fn函数内部的this指向(必需);

             arg1, arg2, arg3, ...argN      函数fn在执行时,传入的实参。(可选)

      (2)fn.apply(thisObj, [array]);

             thisObj       在fn函数内部的this指向(必需);

             数组对象       将数组的所有元素值当做fn执行时的实参。(可选)

     4. 面试题

        (1)var name = "The Window";  

               var object = {    
                  name: "My Object",
          getNameFunc: function() {      
                      return function() {        
                           return this.name;      
                      };    
                  }  
              };  
             alert(object.getNameFunc()());     // the window

          解析:return返回的是一个匿名函数function,普通函数this指向window

       (2)var name = "The Window";  

               var object = {    
                 name: "My Object",
              getNameFunc: function() {      
                      var that = this;     //此时this指向object对象 
                      return function() {        
                          return that.name;   //that也指向object对象 that.name就是My Object   
                       };    
                  }  
              };  
             alert(object.getNameFunc()());     // My Object

     (3)var age=100;

            function test() {
                this.age=50;
               return function () {
                   return this.age;
               }
           }

          var m=new test();  

          console.log(m.age);     // undefined      

          console.log(m());       // 100

          var n=test();

          console.log(n());        // 50

       5.上下文模式应用

           1. 借用方法

           (1)数组合并

               a.实现两个数组合并

                  var arr1=[1,2,3,4];

                  var arr2=[5,6,7,8];
                  arr1.push.apply(arr1,arr2);
                  console.log(arr1);

              b.将两个数组添加到对象中

                  var arr1=[1,2,3,4];

                  var arr2=[5,6,7,8];

                  var o={};

                  arr1.push.apply(o,arr1.concat(arr2));
                  console.log(o);

           (2)借用Math对象方法

                  var arr = [1, 5, 9, 20, 10];

                  console.log(Math.max.apply(null, arr));

           (3)获取对象类型

                 function _type(obj) {

                   if(obj === null) return "null";

                   else if(typeof obj === "object") return /^functions*(w+)(/.exec(obj.constructor)[1].toLowerCase();       

                   else return typeof obj;
                }

                  console.log(_type(null));         // "null"
                  console.log(_type(undefined));           // "undefined"
                  console.log(_type([]));         //"array"
                  console.log(_type("string"));       // "string"
                  function foo() {}
                  console.log(_type(foo));        //function

            (4)实现伪数组对象转换为真数组                  

                     <div>d1</div>
                     <div>d2</div>
                     <div>d3</div>
                     <div>d4</div>

                    <script>                          

                         // NodeList 伪数组对象
                         var doms = document.querySelectorAll('div')
                         // 伪数组变成真数组
                         var arrDom = Array.prototype.slice.call(doms);

                    </script>

           2.  实现借用构造函数继承            

                function Person(name, age, gender, high) {
                     this.name = name;
                     this.age = age;
                     this.gender = gender;
                     this.high = high;
               }

                function Teacher(name, age, gender, high, codeNo, cellphoneNo) {
                     Person.apply(this, Array.prototype.slice.call(arguments, 0, 4));
                     this.codeNo = codeNo;
                     this.cellphoneNo = cellphoneNo;
                }

                var t = new Teacher('guojing', 18, 'boy', '226', '91248', '13813813811');
                console.log(t);

           3.  改变this指向

             前面已经介绍,这里就不过多陈述了。

        总之,无论学什么,都要静下心来,一步一个脚印踏踏实实的走下来,然后就会发现不一样的世界。姑娘,加油吧!

原文地址:https://www.cnblogs.com/fatimah1214/p/6063578.html