资讯专栏INFORMATION COLUMN

高程3总结#第7章函数表达式

sevi_stuo / 579人阅读

摘要:匿名函数可以用来模仿块级作用域来避免这个问题这里是块级作用域代码定义并立即调用了一个匿名函数,将函数声明包含在一对圆括号中,表示它实际上是一个函数表达式,而紧随其后的另一对圆括号会立即调用这个函数。

函数表达式 递归

递归函数是在一个函数通过名字调用自身的情况下构成的

function factrial(num){
  if(num<=1){
    return 1;
  }else {
    return num*factrial(num-1);
  }
}

argument.callee是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用

function factorial(num){
  if(num<=1){
    return 1;
  }else {
    return num*argument.callee(num-1)
  }
}

严格模式下不能通过脚本访问argument.callee,访问这个属性会导致错误,不过可以使用命名函数表达式类达成相同的结果

var factorial=(function f(num){
  if(num<=1){
    return 1;
  }else {
    return num*f(num-1);
  }
})

闭包

闭包是指有权访问另一个函数作用域中的变量的函数

function compare(value1,value2){
  if(value1value2){
    return 1;
  }else {
    return 0;
  }
}
var result=compare(5,10)

//创建函数
var compareNames = createComparisonFunction("name");
//调用函数
var result = compareNames({ name: "Nicholas" }, { name: "Greg" });
//解除对匿名函数的引用(以便释放内存)
compareNames = null;

闭包与变量

闭包只能取得包含函数中任何变量的最后一个值,i值为10

function creatFunctions(){
  var result=new Array();
  for(var i=0;i<10;i++){
    result[i]=function(){
      return i;
    };
  };
  return result;
}

通过匿名函数强制让闭包的行为符合预期

function createFuntion(){
  var result=new Array();
  for(var i=0;i<10;i++){
    result[i]=function(num){
      return function(){
        return num;
      };
    }(i);
  }
  return result;
}

关于this对象

匿名函数的执行环境具有全局性,因此其this对象通常指向window

把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以了让闭包访问这个对象了

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

定义米明函数之前,我们把this对象赋值给了一个名叫that的变量,而在定义了这个闭包之后,闭包也可以访问这个变量,因此它是我们在包含函数中特意声明的一个变量,即使在函数返回之后,that也仍然引用这object

内存泄漏

如果闭包作用域中保存着一个HTML元素,那么久意味着该元素将无法被销毁

function assignHandler(){
  var element=docunemt.getElementById("someElement");
  element.onclick=function(){
    alert(element.id)
  }
}

以上代码段中的element占用的内存永远不会被回收

function assignHandler(){
  var element=document.getElementById("someElement");
  var id=element.id;
  element.onclick=function(){
    alert(id);
  }
  element=null;
}

模仿块级作用域
function outputNumbers(count){
  for(var i=0;i

JavaScript从来不会告诉你是否多次声明了同一个变量,遇到这种情况,只会对后续的声明视而不见,不过会执行后续声明中的变量初始化。匿名函数可以用来模仿块级作用域来避免这个问题

(function(){
  //这里是块级作用域
})()

代码定义并立即调用了一个匿名函数,将函数声明包含在一对圆括号中,表示它实际上是一个函数表达式,而紧随其后的另一对圆括号会立即调用这个函数。

function outputNumbers(count){
  (function(){
    for(var i=0;i

这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。一般来说,我们应该尽量少向全局作用域中添加变量和函数

私有变量

JavaScript中灭有私有成员的概念,所以对象属性都是共有的。任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量,私有变量包括函数的参数、局部变量和在函数内部定义的其他函数。

如果在函数内部创建一个闭包,那么闭包通过自己的作用域链也可以访问函数内的变量

静态私有变量
(funciton(){
  //私有变量和私有函数
  var privateVariable=10;
  function privateFunction(){
    return false;
  }
  //构造函数
  MyObject=function(){}
  //公有/特权方法
  MyObject.prototype.publicMethod=function(){
    privateVariable++;
    return privateFunciton();
  }
})();

在私有作用域中,首先定义了私有变量和私有函数,然后又定义了构造函数及其公有方法

模块模式

模块模式是为单例创建私有变量和特权方法。单例指的就是只有一个实例的对象。按照惯例,JavaScript是以字面量的方式来创建单例对象的

var singleton={
  name:value,
  method:function(){
    //这里是代码方法
  }
}

模块模式通过为单例添加私有变量和特权的方法能够使其得到增强

var singleton=function(){
  //私有变量和私有函数
  var privateVariable=10;
  funciton privateFunction(){
    return false;
  }
  //特权/公有方法和属性
  return {
    publicProperty:true,
    publicMethod:function(){
      privateVariable++;
      return privateFunction();
    }
  };
}();

增强的模块模式
var application = function(){
//私有变量和函数
var components = new Array();
//初始化
components.push(new BaseComponent());
//创建 application 的一个局部副本
var app = new BaseComponent();
//公共接口
app.getComponentCount = function(){
  return components.length;
};
app.registerComponent = function(component){
  if (typeof component == "object"){
    components.push(component);
  }
};
//返回这个副本/
return app;
}();

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97620.html

相关文章

  • 高程3总结#17错误处理与调试

    错误处理与调试 错误处理 try-catch语句 try{ //可能会导致错误的代码 }catch(error){ //在错误发生时怎么处理 } 发生错误时可以显示浏览器给出的信息 try{ window.someNonexistentFunction(); }catch(error){ alert(error.message); } 在try-catch语句中是可选的,但...

    fizz 评论0 收藏0
  • 高程3总结#18JavaScript与XML

    摘要:在基于使用命名空间的文档求值时,需要使用对象。第四个参数的取值类型是下列常量之一,返回与表达式匹配的数据类型。,返回字符串值。这是最常用的结果类型。集合中节点的次序与它们在文档中的次序一致。 JavaScript与XML 浏览器对XML DOM的支持 DOM2级核心 在通过JavaScript处理XML时,通常只使用参数root,因为这个参数指定的是XML DOM文档元素的标签名 v...

    gaosboy 评论0 收藏0
  • 高程3总结#8BOM

    摘要:对象的核心对象是,它表示浏览器的一个实例。而和则表示该容器中页面视图区的大小。在中,与返回相同的值,即视口大小而非浏览器窗口大小。第三个参数是一个逗号分隔的设置字符串,表示在新窗口中都显示哪些特性。这应该是用户打开窗口后的第一个页面 BOM window对象 BOM的核心对象是window,它表示浏览器的一个实例。在浏览器中,window对象有双重角色,它既是通过JavaScript访...

    MASAILA 评论0 收藏0
  • 高程3总结#9客户端检测

    摘要:能力检测无法精确地检测特定的浏览器和版本。用户代理检测通过检测用户代理字符串来识别浏览器。用户代理检测需要特殊的技巧,特别是要注意会隐瞒其用户代理字符串的情况。 客户端检测 能力检测 能力检测的目的不是识别特定的浏览器,而是识别浏览器的能力,采用这种方式不必顾忌特定的浏览器,只要确定浏览器支持的特定的能力,就能给出解决方案,检测基本模式 if(object.propertyInQu...

    BigNerdCoding 评论0 收藏0
  • 高程3总结#14表单脚本

    表单脚本 表单的基础知识 HTMLFormElement有自己独特的属性和方法 acceptCharset,服务器能够处理的字符集,等价于HTML中的accept-charset特性 action,接受请求的URL,等价于HTML中的action特性 elements,表单中所有控件的集合 enctype,请求的编码类型,等价于HTML中的enctype特性 length,表单中控件的数量 m...

    Tony 评论0 收藏0

发表评论

0条评论

sevi_stuo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<