当前位置: 首页 > 图文教程 > 网络编程 > Javascript > JavaScript中的Function对象

Javascript
jQuery生成asp.net服务器控件的代码
javascript 实现的完全兼容鼠标滚轴缩放图片的代码
JavaScript学习笔记(十七)js 优化
使用SyntaxHighlighter实现HTML高亮显示代码的方法
javascript contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
利用jQuery 实现GridView异步排序、分页的代码
jquery.lazyload 实现图片延迟加载jquery插件
Lazy Load 延迟加载图片的 jQuery 插件
jquery 插件实现图片延迟加载效果代码
javascript小数计算出现近似值的解决办法
jquery1.4后 jqDrag 拖动 不可用
jquery 应用代码 方便的排序功能
选择TreeView控件的树状数据节点的JS方法(jquery)
jquery 图片Silhouette Fadeins渐显效果
JQuery Dialog(JS 模态窗口,可拖拽的DIV)
javascript 同时在IE和FireFox获取KeyCode的代码
js 键盘记录实现(兼容FireFox和IE)
javascript 函数速查表
jQuery AnythingSlider滑动效果插件
经典海量jQuery插件 大家可以收藏一下

Javascript 中的 JavaScript中的Function对象


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 106 ::
收藏到网摘: n/a

JavaScript中的Function对象是函数,函数的用途分为3类:

  1. 作为普通逻辑代码容器;
  2. 作为对象方法;
  3. 作为构造函数。

1.作为普通逻辑代码容器

function multiply(x, y){
return x*y;
}

函数multiply封装了两位数的乘法运算公式:

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

创建函数实例的方式有3种。第一种是声明式,即像声明变量一样,将通过function(){}标识符创建的匿名函数直接赋值给变量,以该变量作为调用时的函数名称:

var multiply = function(x, y){
return x*y;
}

第二种是定义式,即以function关键字后跟函数名称及(){}来直接定义命名函数,前面第一个multiply函数就是通过定义式创建的。

第三种是构造函数式,即通过new运算符调用构造函数Function来创建函数。这种方式极不常用,因此就不作介绍了。

在创建函数的3种方式中,声明式和定义式还存在细微的差别。比如下列代码中的函数采用声明式:

var example = function(){
return 1;
}
example();
var example = function(){
return 2;
}
example();

执行结果如下:
1
2

而如果采用定义式,即:

function example(){
return 1;
}
example();
function example(){
return 2;
}
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 = “3 months”;
dog.shout = function(){
return “Hello, My name is “+ this.name + ” and I am ” + this.age + ” old!”;
}
dog.shout(); // “Hello, My name is heibao and I am 3 months old!”

有意思的是,对象也可以借用其他对象的方法:

var cat = {};
cat.name = “xiaohua”;
cat.age = “2 years”;
cat.greet = dog.shout;
cat.greet(); // “Hello, My name is xiaohua and I am 2 years old!”

另外,使用函数对象的call和apply方法,还可以动态指定函数或方法的调用对象:

dog.shout.call(cat); // “Hello, My name is xiaohua and I am 2 years old!”

或者

dog.shout.apply(cat); // “Hello, My name is xiaohua and I am 2 years old!”

3.作为构造函数

JavaScript是通过构造函数来模拟面向对象语言中的类的。例如:

function Animal(sort, character){
this.sort = sort;
this.character = character;
}

以Animal作为构造函数,就可以像下面这样创建一个新对象:

var dog = new Animal(”mammal”,”four legs”);

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

dog.sort; // mammal
dog.character; // four legs
dog.constructor; // Animal

聪明的读者结合前面介绍的内容,可能会认为使用new运算符调用构造函数创建对象的过程也可以像下面这样来实现:

var dog = {};
Animal.call(dog, “mammal”,”four legs”);

表面上看,这两行代码与var dog = new Animal(”mammal”,”four legs”);是等价的,其实却不是。虽然通过指定函数的执行环境能够部分达到初始化对象的目的,例如空对象dog确实获得了sort和character这两个属性:

dog.sort; // mammal
dog.character; // four legs
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, good lucky!”;
dog.greet; // undefined

事实上,在Firefox中,__proto__属性也是可写的:

Animal.prototype.greet = “Hi, good lucky!”;
dog.__proto__ = Animal.prototype;
dog.greet; // Hi, good lucky!

但这样做只能在Firefox中行得通。考虑到在兼容多浏览器,必须依赖于new运算符,才能实现基于原型的继承。