zoukankan      html  css  js  c++  java
  • JavaScript语言精粹_第四章

    4.1 函数对象

      在JavaScript中,函数就是对象。对象是“名/值”对的集合并拥有一个连到原型对象的隐藏链接。对象字面量产生的对象连接到Object.prototype。函数对象连接到Function.prototype(该原型对象本身连接到object.prototype)

      每个函数对象在创建是也随带一个prototype属性,它的值是一个拥有constructor属性且至即为该函数的对象

      函数可以存放变量,可以被当作参数传递给其他函数,也可以在返回函数。

      因为函数是对象,所以它可以像其他的值一样被使用,也可以拥有方法

    4.3 调用

      调用一个函数将暂停当前函数的执行,传递控制权和参数给新函数。每个函数接受两个附加的参数:this和arguments。

      在JavaScript中有四种调用模式:方法调用模式,函数调用模式,构造器调用模式和apply调用模式。这些模式在如何初始化关键参数this上存在差异。

      方法调用模式

        函数保存为对象的一个属性时,它被称为方法。方法可以通过this去访问,this到对象的绑定发生在调用的时候,这个“超级”迟绑定使得函数可以对this高度复用。

      函数调用模式

        当一个函数并非一个对象的属性时,它被当作一个函数来调用(在对象的方法中再次定义的方法)。

        当函数以此模式调用时,this被绑定到全局对象(这是一个bug),可以该方法定义一个变量并给它赋值为this,那么内部函数就可以通过那个变量访问到this

      构造器调用模式

        如果在一个函数前面带上new来调用,那么将创建一个隐藏链接到该函数的prototype成员的新对象,同时this将对绑定到那个新对象上。

        结合new前缀调用的函数被称为构造器函数,它们保存在以大写格式命名的变量里,如果调用构造器函数时没有在前面加上new,可能会发生非常糟糕的事情(在其他地方报错,可能你要改一天。。。),既没有编译时警告,也没有运行时警告,所以大写约定非常重要。

      Apply调用模式

        apply让我们构建一个参数数组并用其去调用函数,它允许我们选择this的值。apply方法接收两个参数,第一个是将绑定给this的值,第二个就是参数数组

    4.4 参数

      当函数被调用时,会得到arguments数组,这使得编写一个无须指定参数个数的函数成为可能。

      可以构造一个将很多个值相加的函数。

      因为这个设计错误,使得arguments并非一个真正的数组,它只是一个“类似数组”的对象,它拥有length属性,但缺少所有的数组方法。

    4.5 返回

      return语句可以用来是函数提前返回。一个函数总是会返回一个值,如果没有制定返回值,则返回undefined。

      如果函数以在前面加上new前缀的方式来调用,且返回值不是一个对象,则返回this(该新对象)

    4.7 给类型增加方法

      JavaScript允许给语言的基本类型增加方法。

      JavaScript没有单独的整数类型,我们可以通过Number.prototype添加一个integer来改善它。

        Number.prototype.integer = function (){

          return Math(this < 0 ? 'ceiling' : 'floor'](this);

        }

      基本类型的原型是公共的结构,所以只在确定没有改方法时才添加它。

    4.8 递归

      递归函数可以非常高效地操作树形结构,比如浏览器端的文档对象模型(DOM),每次递归调用时处理给定树的一小段。

      var walk_the_DOM = function walk(node,func){

        func(node);

        node = node.firstChild;

        while(node){

          walk(node,func);

          node = node.nextSibling;

        }

      };

      var getElementsByAttrbute = function(attr,value){

        var rusults = [];

        walk_the_DOM(document.body,function(node){

          var actual = node.nodeType === 1 && node.getAttrbute(att);

          if(typeof actual === 'string' && (actual === value || typeof value !== 'string')){

            results.push(node);

          }

        });

        return results;

      };

      一些语言提供了尾递归优化,这意味着如果一个函数返回自身递归调用的结果,那么调用的过程会被替换为一个循环,它可以显著提高速度。但这里JavaScript没有提供尾递归优化,深度递归的函数可能会因为返回堆栈溢出而运行失败。

    4.9 作用域

      JavaScript有函数作用域,但是没有块级作用域。最好的做法是在函数整体的顶部声明函数中可能用到的所有变量

    4.10 闭包

      内部函数拥有比它的外部更长的生命周期

      一个常见的例子

        var add_the_handlers = function (nodes) {

          var i;

          for(i=0; i < nodes.length; i += 1){

            nodes[i].onclick = function (e){

              alert(i);

            }

          }

        };

        它总是会显示节点的数目,是因为事件处理器函数绑定了变量i,而不是函数在构造是的变量i的值

        var add_the_handlers = function (nodes) {

          var i;

          for(i=0; i < nodes.length; i += 1){

            nodes[i].onclick = function (i){

              return function(e){

                alert(i);

              };

            }(i);

          }

        };

     4.11 回调

      函数可以让不连续事件的处理变得更容易,可以发起异步的请求,提供一个当服务器的响应到达时将被调用的回调函数。

    4.12 模块

      通过使用闭包和函数来构造模块,模块是一个提供接口却隐藏状态与实现的函数或对象,通过使用函数去产生模块,我们可以摈弃全局变量的使用,从而缓解这个糟糕的特性带来的影响。

      模块的一般形式:一个定义了私有变量和函数的函数;利用闭包创建可以访问私有变量和函数的特权函数;最后返回这个特权函数,或者把他们保存到一个可访问到的地方。

      模块模式通常通过单例模式使用。

    4.13 级联

      让一些方法返回this而不是undefined,就可以启用级联。

      在一个级联中,我们可以在单独一条的语句中依次调用同一个对象的很多方法。

    4.14 套用

      可以将函数与传递给它的参数相结合去产生出一个新的函数

    4.15 记忆

      在计算机领域中,记忆是主要用于加速程序计算的一种优化技术,是的函数避免重复演算之前已被处理的输入,而返回以缓存的结果。

      JavaScript的对象和数组要实现这种优化是非常方便的

      var fibonacci = function (n) {

        return n < 2 ? n : fibonacci (n - 1) + fibonacci (n - 2);

      } 

      for (var i = 0; i <= 10; i += i){

        document.writeIn( i + '=' + fibonacci(i));

      }

      这里调用了11次,而它自身调用了442次去计算可能已被刚计算过的值。

      var fibonacci = function(){

        var memo = [0, 1];

        var fib = function (n){

          var result = memo[n];

          if(typeof result !== 'number') {

            result = fib(n - 1) + fib(n -2);

            memo[n] = result;

          } 

          return result;

        };

        return fib;

      }();

      这个函数返回同样的结果,调用了它11次,它自身调用了18次去取得之前存储的结果。  

  • 相关阅读:
    java常用类
    java throw和catch同时使用
    HTML5 input 类型: email及url
    Android中集成支付宝
    HTML5 预加载
    SQLite数据库
    Android开发中如何加载API源码帮助开发
    Java中的static
    HTML5 Web Storage 特性
    gdal1.10编译经验
  • 原文地址:https://www.cnblogs.com/tyjz/p/7197265.html
Copyright © 2011-2022 走看看