通俗的来讲,函数是由事件驱动的或者当它被调用时执行的可重复使用的代码快。它是 JavaScript 语言一个即重要又复杂的组成部分,任何一个 JavaScript 框架,如 Dojo、jQuery 等都是有成百上千个函数组成的。函数的使用不仅提高了代码本身的可读性,也为它的扩展提供了可能,同时还降低了维护成本,加快 web 项目的开放进度;尤其是在多人参与的敏捷开发中。
通常函数的定义是通过 function 语句实现的:
清单 1.函数定义
funcname 是要定义的函数名,是一个标识符,而不是字符串或者表达式;紧跟函数名后面的是用括号括起来的参数列表,参数之间用逗号隔开;最后,也是这个函数的核心部分:函数体,它是由一行或者多行代码组成并且是用大括号括起来的。
函数定义描述的是一个静态的程序结构,当 JavaScript 解析器遇到一个函数定义时,它就被解析并存储构成函数体的语句,然后定义一个和该函数名同名的全局或者某个对象属性来保存。当该函数被调用时,里面的函数体才真正的被执行。如:
清单 2
定义一个函数,最为普遍的是直接使用 function 关键字来定义,又称函数声明式(function declaration),如上面定义的 f 函数,但是 function 语句并非是定义函数的惟一方法。在 ECMAScript v1 和 JavaScript v1.1 中,还可以使用 Function () 构造函数和 new 运算符动态地定义函数,如下:
var myfunc=new Function ('x', 'y', 'alert(x+y)');
这行代码创建了一个新函数,该函数和下面使用 function 方法定义的函数是等价的:
清单 3.
Function () 定义中,前面两个是参数,参数可以是任意多个字符串;第三个是函数体,可以包含任何 JavaScript 语句,语句之间用分号隔开。如果没有参数,传一个函数体即可。由于传递给 Function () 函数中,没有一个字符串是用来声明函数名的,所以它是一个匿名函数。
使用 Function()构造函数来定义函数允许我们动态的来定义和编译一个函数,而不是限定在 function 预编译的函数体中。但同时也会带来负面影响,因为每次调用这个函数都要对它进行编译,对性能有一定的影响,尤其是在循环体中。
函数定义的第三种方式是函数直接量,ECMAScript v3 定义了函数直接量,JavaScript 1.2 实现了它。函数直接量是一个表达式,它即可以定义一个匿名函数,也可以定义一个带函数名的函数:
清单 4.
注意:调用时得用定义的变量名,如f(4),而不能fact(4).
函数直接量和使用 Function()构造函数来创建函数的方法非常相似,因为两种方法都是通过 JavaScript 的表达式创建的,而不是由语句创建的;所以使用他们的方式也更灵活,尤其是那些只使用一次,而且不需要命名的函数。比如把它传递给其他的函数:
清单 5.
三种方式的区别,可以从作用域、效率以及加载顺序来区分。首先,从作用域上来说,函数声明式和函数直接量使用的是局部变量,而 Function()构造函数却是全局变量:
清单 6.
其次是执行效率上来说,Function()构造函数的效率要低于其他两种方式,尤其是在循环体中,因为构造函数每执行一次都要重新编译,并且生成新的函数对象:
清单 7.
由此可见,在循环体中,函数直接量的执行效率是 Function()构造函数的 0.6 倍。所以在 Web 开发中,为了加快网页加载速度,提高用户体验,我们不建议选择 Function ()构造函数方式来定义函数。
最后是加载顺序,function 方式(即函数声明式)是在 JavaScript 编译的时候就加载到作用域中,而其他两种方式则是在代码执行的时候加载,如果在定义之前调用它,则会返回 undefined:
清单 8.
当深入 JavaScript 编程世界时,您将遇到的基本概念之一是方法和函数之间的区别。虽然方法和函数在 JavaScript 中都起着至关重要的作用,但它们具有不同的目的并以不同的方式使用。在这篇博文中,我们将揭开这两个概念的神秘面纱,让您清楚地了解它们的差异。
让我们深入了解有关 function 和 method 的更多详细信息:
function 的核心是执行特定任务或一组任务的可重用代码块。将其视为一组预定义的指令,您可以在需要时调用或调用它们。函数就像 JavaScript 代码的构建块,允许您将复杂的任务分解为更小的、可管理的部分。
这是一个函数的基本示例:
function greet(name) {
return "Hello, " + name + "!";
}
在此代码段中, greet 是一个函数,它采用单个参数 name ,并返回问候语字符串。 JavaScript 中的函数用途广泛,可以在各种上下文中使用,从像这样的简单操作到复杂的逻辑。
现在,我们来谈谈方法。 JavaScript 中的方法本质上是一个函数,但有一个关键的区别——它与一个对象关联。方法是存储为对象属性的函数,用于定义该对象的行为。下面举个例子来说明:
let person={
firstName: "John",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
};
在此示例中, fullName 是 person 对象的方法。它使用 this 关键字来访问对象的属性。
让我们重点介绍 JavaScript 中函数和方法之间的主要区别:
理解 JavaScript 中 methods 和 functions 之间的区别对于编写清晰高效的代码至关重要。函数提供了模块化和可重用性,而方法则为我们提供了一种遵循面向对象编程原则将行为封装在对象内的方法。
总之,虽然所有方法都是函数,但并非所有函数都是方法。区别在于它们与对象的关联以及它们如何在这些对象的上下文中使用。
JavaScript 函数有 4 种调用方式。
每种方式的不同方式在于 this 的初始化。
this 关键字
一般而言,在Javascript中,this指向函数执行时的当前对象。
注意 this 是保留关键字,你不能修改 this 的值。 |
调用 JavaScript 函数
我们知道如何创建函数。
函数中的代码在函数被调用后执行。
作为一个函数调用
实例
function myFunction(a, b) {
return a * b;
}
myFunction(10, 2); // myFunction(10, 2) 返回 20
以上函数不属于任何对象。但是在 JavaScript 中它始终是默认的全局对象。
在 HTML 中默认的全局对象是 HTML 页面本身,所以函数是属于 HTML 页面。
在浏览器中的页面对象是浏览器窗口(window 对象)。以上函数会自动变为 window 对象的函数。
myFunction() 和 window.myFunction() 是一样的:
实例
function myFunction(a, b) {
return a * b;
}
window.myFunction(10, 2); // window.myFunction(10, 2) 返回 20
这是调用 JavaScript 函数常用的方法, 但不是良好的编程习惯 全局变量,方法或函数容易造成命名冲突的bug。 |
全局对象
当函数没有被自身的对象调用时, this 的值就会变成全局对象。
在 web 浏览器中全局对象是浏览器窗口(window 对象)。
该实例返回 this 的值是 window 对象:
实例
function myFunction() {
return this;
}
myFunction(); // 返回 window 对象
函数作为全局对象调用,会使 this 的值成为全局对象。使用 window 对象作为一个变量容易造成程序崩溃。 |
函数作为方法调用
在 JavaScript 中你可以将函数定义为对象的方法。
以下实例创建了一个对象 (myObject), 对象有两个属性 (firstName 和 lastName), 及一个方法 (fullName):
实例
var myObject={
firstName:"John",
lastName: "Doe",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
myObject.fullName(); // 返回 "John Doe"
fullName 方法是一个函数。函数属于对象。 myObject 是函数的所有者。
this对象,拥有 JavaScript 代码。实例中 this 的值为 myObject 对象。
测试以下!修改 fullName 方法并返回 this 值:
实例
var myObject={
firstName:"John",
lastName: "Doe",
fullName: function () {
return this;
}
}
myObject.fullName(); // 返回 [object Object] (所有者对象)
函数作为对象方法调用,会使得 this 的值成为对象本身。 |
使用构造函数调用函数
如果函数调用前使用了 new 关键字, 则是调用了构造函数。
这看起来就像创建了新的函数,但实际上 JavaScript 函数是重新创建的对象:
实例
// 构造函数:
function myFunction(arg1, arg2) {
this.firstName=arg1;
this.lastName=arg2;
}
// Thiscreates a new object
var x=new myFunction("John","Doe");
x.firstName; // 返回 "John"
构造函数的调用会创建一个新的对象。新对象会继承构造函数的属性和方法。
构造函数中 this 关键字没有任何的值。this 的值在函数调用时实例化对象(new object)时创建。 |
作为函数方法调用函数
在 JavaScript 中, 函数是对象。JavaScript 函数有它的属性和方法。
call() 和 apply() 是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。
实例
function myFunction(a, b) {
return a * b;
}
myFunction.call(myObject, 10, 2); // 返回 20
实例
function myFunction(a, b) {
return a * b;
}
myArray=[10,2];
myFunction.apply(myObject, myArray); // 返回 20
两个方法都使用了对象本身作为第一个参数。 两者的区别在于第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。
在 JavaScript 严格模式(strict mode)下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象。
在 JavaScript 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。
通过 call() 或 apply() 方法你可以设置 this 的值, 且作为已存在对象的新方法调用。 |
如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!
*请认真填写需求信息,我们会在24小时内与您取得联系。