Javascript 中 Function 三大用途

JavaScript中的Function对象是函数,Script中的Function(函数)对象的有三大用途。JavaScript中的Function对象是函数,函数的用途分为3类:编程

  a.做为普通逻辑代码容器;b.做为对象方法;c.做为构造函数。浏览器

1.做为普通逻辑代码容器app

      function multiply(x,y){  returnx*y;  } 函数multiply封装了两位数的乘法运算公式:函数

      var  product=multiply(128,128);//product=16384   建立函数实例的方式有3种。第一种是声明式,即像声明变量同样,将经过function(){}标识符建立的匿名函数直接赋值给变量,以该变量做为调用时的函数名称:this

      var  multiply=function(x,y){  returnx*y;  } 第二种是定义式,即以function关键字后跟函数名称及(){}来直接定义命名函数,前面第一个multiply函数就是经过定义式建立的。url

      第三种是构造函数式,即经过new运算符调用构造函数Function来建立函数。这种方式极不经常使用。prototype

在建立函数的3种方式中,声明式和定义式还存在细微的差异。好比下列代码中的函数采用声明式:对象

    var  example=function(){  return1;  }  example();  varexample=function(){  return2;  }  example();    执行结果以下:继承

   1  2 而若是采用定义式,即:ip

function example(){  return1;  }  example();  functionexample(){  return2;  }  example(); 那么会获得另外一种结果:

  2  2 即,在采用定义式建立同名函数时,后建立的函数会覆盖先建立的函数。这种差异是因为JavaScript解释引擎的工做机制所致使的。JavaScript解释引擎在执行任何函数调用以前,首先会在全局做用域中注册以定义式建立的函数,而后再依次执行函数调用。因为注册函数时,后定义的函数重写了先定义的函数,所以不管调用语句位于何处,执行的都是后定义的函数。相反,对于声明式建立的函数,JavaScript解释引擎会像对待任何声明的变量同样,等到执行调用该变量的代码时才会对变量求值。因为JavaScript代码是从上到下顺序执行的,所以当执行第一个example()调用时,example函数的代码就是首先定义代码;而当执行第二个example()调用时,example函数的代码又变成了后来定义的代码。

2.做为对象方法

   JavaScript在解析代码时,会为声明或定义的函数指定调用对象。所谓调用对象,就是函数的执行环境。若是函数体内有以关键字this声明的变量,则this引用的就是调用对象。

事实上,在普通的函数中,也存在调用对象,只不过这个调用对象是默认的全局window对象而已。例如:

   var  product=window.multiply(128,128);//product=16384

   这说明,默认状况下,在全局做用域中定义或声明的函数的调用对象就是window。

   在面向对象编程中,一般将做为对象成员的函数称为方法。例如:

   var dog={};  dog.name=“heibao”;  dog.age=“3months”;  dog.shout=function(){  return“Hello,Mynameis“+this.name+”andIam”+this.age+”old!”;  }       dog.shout();//“Hello,MynameisheibaoandIam3monthsold!”    对象也能够借用其余对象的方法:

   var cat={};  cat.name=“xiaohua”;  cat.age=“2years”;  cat.greet=dog.shout;  cat.greet();//“Hello,MynameisxiaohuaandIam2yearsold!” 另外,使用函数对象的call和apply方法,还能够动态指定函数或方法的调用对象:

   dog.shout.call(cat);  //“Hello,MynameisxiaohuaandIam2yearsold!”    或者    dog.shout.apply(cat);  //“Hello,MynameisxiaohuaandIam2yearsold!”

3.做为构造函数 JavaScript是经过构造函数来模拟面向对象语言中的类的。例如:

   function  Animal(sort,character){  this.sort=sort;  this.character=character;  } 以Animal做为构造函数,就能够像下面这样建立一个新对象:

   var  dog=newAnimal(”mammal”,”fourlegs”);    建立dog的对象的过程以下:首先,new运算符建立一个空对象({}),而后以这个空对象为调用对象调用函数Animal,为这个空对象添加两个属性sort和character,接着,再将这个空对象的默认constructor属性修改成构造函数的名称(即Animal;空对象建立时默认的constructor属性值是Object),而且将空对象的__proto__属性设置为指向Animal.prototype——这就是所谓的对象初始化。最后,返回初始化完毕的对象。这里将返回的新对象赋值给了变量dog。

dog.sort;//mammal  dog.character;//fourlegs  dog.constructor;//Animal 聪明的读者结合前面介绍的内容,可能会认为使用new运算符调用构造函数建立对象的过程也能够像下面这样来实现:

   var  dog={};  Animal.call(dog,“mammal”,”fourlegs”); 表面上看,这两行代码与var  dog=newAnimal(”mammal”,”fourlegs”);是等价的,其实却不是。虽然经过指定函数的执行环境可以部分达到初始化对象的目的,例如空对象dog确实得到了sort和character这两个属性:dog.sort;//mammal  dog.character;//fourlegs  dog.constructor;//Object——注意,没有修改dog对象默认的constructor属性 可是,最关键的是新建立的dog对象失去了经过Animal.prototype属性继承其余对象的能力。只要与前面采用new运算符调用构造函数建立对象的过程对比一下,就会发现,new运算符在初始化新对象期间,除了为新对象添加显式声明的属性外,还会对新对象进行了一番“暗箱操做”——即将新对象的constructor属性重写为Animal,将新对象的__proto__属性设置为指向Animal.prototype。虽然手工“初始化对象”也能够将dog.constructor重写为Animal,但根据ECMA262规范,对象的__proto__属性对开发人员是只读的,对它的设置只能在经过new运算符建立对象时由JavaScript解释引擎替咱们完成。 JavaScript是基于原型继承的,若是不能正确设置对象的__proto__属性,那么就意味着默认的继承机制会失效:

Animal.prototype.greet=“Hi,goodlucky!”;  dog.greet;//undefined 事实上,在Firefox中,__proto__属性也是可写的:

Animal.prototype.greet=“Hi,goodlucky!”;  dog.__proto__=Animal.prototype;  dog.greet;//Hi,goodlucky! 但这样作只能在Firefox中行得通。考虑到在兼容多浏览器,必须依赖于new运算符,才能实现基于原型的继承。

相关文章
相关标签/搜索