首页 > 代码库 > 面向对象第5天

面向对象第5天

  今天是学习面向对象的第五天,感觉今天听课比昨天还要混乱,可能是真的到了难的地方了,特别是闭包的知识点,尤其在闭包中实现AJAX获取json数据,代码量加大,一时接受不了呢,所以继续总结知识点。

  一、补充昨天知识点

       1. 闭包的概念。

         概念:可以访问其他函数内部数据的函数。

         注意:在js中,函数内部的数据在外部无法访问。为了访问函数内部的数据,提出闭包技术。

      2. 垃圾回收机制

          两种方式分别是:引用计数、标记清除。

               引用计数:变量默认计数为0,如果有其他数据对其有使用,就引用计数加1,;如果对该变量使用的数据释放了,引用计数减1,在一定周期后,如果变量引用计数为0,就将回收掉。

               标记清除:如果变量进入了一个执行环境,此时该变量被标记为不可回收;如果变量出了执行环境,此时该变量被标记为可回收。在一定周期后,如果变量被标记为可回收,就将其回收掉。

               从文档的根节点尝试找一条路径可以到达变量。如果找到了,就将其变量标记为不可回收;否则标记为可回收。

      3.面试题  

// 1:
var a;
if("a" in window){
a = 10;
} else {
a = 20;
}
console.log(a); //10

var name = 1;
console.log(typeof window.name); //string
console.log(typeof name); //string
console.log(window.name === name); //true

// 2
function fn(a) {
console.log(a); //function a() { console.log(10);}

function a() {
console.log(10);
}
var a = 10;
console.log(a); //10
}

fn(100); 

  二、新知识点

    1. 作用域种类

       弱类型语言:大部分为静态作用域。

       强类型语言:动态作用域。

   2. 函数声明最好不要放在if语句块内部

     原因:现代浏览器不会将函数声明提升,早起的浏览器会得到提升

     面试题案例:

        if(true){
             function a() {
                 console.log(1);
                 }
       } else {
             function a() {
                console.log(0);
             }
       }

       a();   //1

      新版本的浏览器会输出1,而IE6浏览器输出0(函数声明提升,同名函数后面的将前面的函数覆盖)。

     3. 小知识点

       当一个匿名函数 作为某个对象的属性值时, 在其内部 只有使用 arguments.callee 来获取 函数。

     4. 闭包的作用

       (1)实现计数的作用------计数器

          function makeCounter() {

             var count = 0;
             return {
               update: function() {
                      count++;
                 },
              get: function() {
                   return count;
                 }
             };
          }

        var personCounter = makeCounter();
         function Person() {
             personCounter.update();
         }

        new Person;
        new Person;
        new Person;
        new Person;
        new Person;
        new Person;
        new Person;
       console.log(personCounter.get()); // 7

      (2)实现沙箱模式---实质就是匿名自调用函数(很多的框架都使用了沙箱模式)

           优点:与外界隔离,即可以分割作用域;内部代码自执行。

                 在实际开发中,可以考虑将全局对象当做实参传入沙箱内部的变量,以提高js性能。

          用例:如果在开发中,遇到只需要执行一次的代码块。可以将其放到沙箱内部。

     (3)实现缓存------优化fib递归调用性能

              //获取fib函数的第n项值得闭包函数

               var fib=function(){
                   var cache=[]; //缓存计算结果
                   return function(n){ //返回fib函数的闭包函数
                        var val=cache[n]; //从缓存从获取数据
                         if(val) return val;  // 如果有值, 直接返回值
                         else{
                                if(n==1||n==2) val=1;  // 如果n的值 为1 或者 2,值为 1
                        else if(n>2) val=arguments.callee(n-1)+arguments.callee(n-2);  // 如果n的值 大于 2, 递归重新求值
                         return cache[n]=val;   // 将重新计算的值,缓存起来并返回
                         }
                     }
                 }();
               console.log(fib(1000));

       (4)实现面向对象的封装

             在Java 中,对象的属性可以 添加 访问修饰符,private, public,而在js并没这些关键字;通过Object.defineProperty(稍后解释)

       (5)科里化:将一个拥有多个参数的函数 转化成 一个单一参数函数 的形式。(案例稍后补充)

       5. 变量的搜索原则:

      当访问一个变量时, 首先在当前作用域上查找,如果找到就直接使用,并停止查找; 

      如果没有找到,就会向上一级作用域上查找,如果找到就直接使用,并停止查找; 

      如果还没有找到就继续向上一级作用域查找,直到全局作用域,如果找到就直接使用,并停止查找; 

      否则报错(xxx is not defined.)

       6.变态的面试题(需要闭包知识点解答)

       function fun(n, o) {
          console.log(o);
          return {
             fun: function(m) {
                  return fun(m, n);
              }
           };
       }
        var a = fun(0); // n = 0 undefined
        a.fun(1); // n = 0 0
        a.fun(2); // n = 0 0
        a.fun(3); // 0
        var b = fun(0).fun(1).fun(2).fun(3); // undefined, 0, 1, 2

       var c = fun(0).fun(1); // undefined, 0
       c.fun(2);  //1
       c.fun(3);  //1

      var d = b.fun();  //3
      d.fun();  //undefined

        

   

            

         

   

面向对象第5天