重操JS旧业第九弹:函数表达式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重操JS旧业第九弹:函数表达式相关的知识,希望对你有一定的参考价值。

函数表达式,什么概念,表达式中的函数表达式。

1 函数申明

function 函数名([函数参数]){

  //函数体

}

js中无论像这样的显示函数什么放在调用之前还是调用之后,都不影响使用,因为js解释引擎会将函数声明提前化,这点很好理解;

2 函数表达式

var functionV=function 函数名([函数参数]){

  //函数体

};

这种方式的一个变量指向了一个函数,仅此而已。js引擎只会把他当作一个函数类型的变量来处理,仅此而已。

3 递归调用

我们知道函数名仅仅是指向函数的指针,那么话外之意,这个函数名可以指向其他变量,也可以为null等等;

function sum(n){return n+sum(n-1);}

这里如果使用函数表达式,那么就会出问题了,来看怎么回事:

var anSum=sum;

sum=null;

anSum(10);//这个时候调用,进行递归的时候其内部还是使用sum指针,但是,但是此时sum已经被改变,导致调用发生异常,这当然不是程序员想看到的结果?怎么办

在函数章节已经知道函数包括几个属性,name,length,arguments,prototype等等,其中arguments又包含一个指向函数的指针变量callee,就代表了函数本身,且callee为只读,所以我们应该这样写递归代码

function sum(n){return n+arguments.callee(n-1);}

4 模仿块级作用域

js中很容易就创建一堆寄宿在window对象下的变量,函数等等,虽然js不说,但这些对象没人管没人问,他就是window在默默管理着,在一个引用很多js文件页面中难免遇到变量函数命名冲突导致覆盖或者不稳定等各种莫名其妙的问题,那么就需要一种机制来使得js代码模块化,变量,函数也模块化,对于外部window这个对象尽量少向他释放一些全局变量,和函数,特别是毫无意义的。这里的机制需要对外部来说是访问不了内部变量很函数,而对于函数内部而言外部的都是公开的都是可以访问的,就好比家庭和公共资源一样的道理。

js中怎样实现模块化的作用域呢?

(function 函数名(){})();//自动调用的函数,像这样申明的函数会自动调用,这样也具有闭合封装的作用域,这种模块化的书写方式其实就是闭包的一种体现,其内部非构造函数定义的变量和函数被称为静态变量

和函数

 

5 静态变量和函数

(function(){

  //静态变量--------通过特殊方法来访问,对于实例对象来说均共享

  var a=1;

  //静态函数-----被实例对象共享

  function sayHell(){console.log(‘0000)};

 

  //申明模块对象

  var module=function(){};

  

//通过特权方法向外暴露

  module.prototype.Accessa=function(){return a;};

  module.prototype.AccessMethodSayhell=function(){return sayHell;};

})();

 

6 私有变量与方法

(function 函数名(){

 

//在构造函数内部定义的

  //私有变量--------通过特殊方法来访问

  var a=1;

  //私有函数-----

  function sayHell(){console.log(‘0000)};

 

//通过this指向的这叫公有变量

  this.name=‘‘;

 

})();

 

7 模块模式

模块模式又称为单例模式,一般来说js中单例都是使用字面量来实现;

var obj={

  name:‘‘,

  say:function(){console.log(‘sssssss‘)}

};

 

但是这样对内部成员name,say均起不到保护和隔离作用,因此这些内部的私有变量应该通过特权方法向外暴露,以控制访问安全性;

var singleton=function(){

  var name=‘‘;

  var say=function(){console.log(‘sssssss‘)};

  

  return {

    Name:name,

    Say:function(){return say;}

  }

};

这样就成为模块模式 一种标配,因为对象本身只会存在一份实例;但是这样有个缺点,就是创建出来的对象没有类型使用类型检测运算符:instanceof也检测不出来,为了解决这个问题,提出增强模块模式。

 

8 增强模块模式

var singleton=function(){

  var name=‘‘;

  var say=function(){console.log(‘sssssss‘)};

  

     var obj=new SubType();//将这些私有成员暴露给指定类型上去,这样返回的单例对象就具有了某个类型的构造函数,也就可以使用instanceof检测。所以说是一种增强;

  obj.Name=name;

  obj.Say=function(){return say;}

  return obj;

};

 

以上是关于重操JS旧业第九弹:函数表达式的主要内容,如果未能解决你的问题,请参考以下文章

重操JS旧业第十弹:闭包

重操JS旧业第三弹:Array

重操JS旧业第二弹:数据类型与类型转换

重操JS旧业第四弹:Date

重操JS旧业第八弹:面向对象与继承

重操JS旧业第六弹:基本类型包装