教材来自<<菜鸟学堂>>
函数定义
JavaScript 使用关键字 function 定义函数。
函数可以通过声明定义,也可以是一个表达式。
函数声明
由于函数声明不是一个可执行语句,所以不以分号结束。
function myFunction(a, b) { return a * b; } var x = myFunction(4, 3) * 2;
函数表达式
var x = function (a, b) { return a * b }; var z = x(4, 3);
以上函数实际上是一个 匿名函数 (函数没有名称)。
上述函数以分号结尾,因为它是一个执行语句。
Function() 构造函数
函数同样可以通过内置的 JavaScript 函数构造器(Function())定义。(2种方式)
var myFunction = new Function("a", "b", "return a * b"); var myFunction = function (a, b) {return a * b} var x = myFunction(4, 3);
在 JavaScript 中,很多时候,你需要避免使用 new 关键字。
函数提升(Hoisting)
提升(Hoisting)是 JavaScript 默认将当前作用域提升到前面去的的行为。
函数可以在声明之前调用:
myFunction(5); function myFunction(y) { return y * y; }
注意:使用表达式定义函数时无法提升。
自调用函数
函数表达式可以 "自调用"。
自调用表达式会自动调用。
如果表达式后面紧跟 () ,则会自动调用。
不能自调用声明的函数。
通过添加括号,来说明它是一个函数表达式:
<p id="demo"></p> <script> (function () { document.getElementById("demo").innerHTML = "Hello! 我是自己调用的"; })(); </script>
以上函数实际上是一个 匿名自我调用的函数 (没有函数名)。
函数是对象
在 JavaScript 中使用 typeof 操作符判断函数类型将返回 "function" 。
但是JavaScript 函数描述为一个对象更加准确。
JavaScript 函数有 属性 和 方法。
function myFunction(a, b) { return arguments.length; // 2 } var txt = myFunction.toString(); // toString() 方法将函数作为一个字符串返回:
函数显式参数(Parameters)与隐式参数(Arguments)
函数显式参数在函数定义时列出。
函数隐式参数在函数调用时传递给函数真正的值。
参数规则
JavaScript 函数定义时显示参数没有指定数据类型。
JavaScript 函数对隐式参数没有进行类型检测。
JavaScript 函数对隐式参数的个数没有进行检测。
默认参数
如果函数在调用时未提供隐式参数,参数会默认设置为: undefined
有时这是可以接受的,但是建议最好为参数设置一个默认值:
function myFunction(x, y) { if (y === undefined) { // 简单式:y = y || 0; y = 0; } }
Arguments 对象
JavaScript 函数有个内置的对象 arguments 对象。
argument 对象包含了函数调用的参数数组。
通过这种方式你可以很方便的找到最后一个参数的值:
因为如果函数调用时设置了过多的参数,参数将无法被引用,因为无法找到对应的参数名。 只能使用 arguments 对象来调用。
x = sumAll(1, 123, 500, 115, 44, 88); function sumAll() { var i, sum = 0; for (i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; }
值传递参数
在函数中调用的参数是函数的隐式参数。
JavaScript 隐式参数通过值来传递:函数仅仅只是获取值。
如果函数修改参数的值,不会修改显式参数的初始值(在函数外定义)。
隐式参数的改变在函数外是不可见的。
对象传递参数
在JavaScript中,可以引用对象的值。
因此我们在函数内部修改对象的属性就会修改其初始的值。
修改对象属性可作用于函数外部(全局变量)。
修改对象属性在函数外是可见的。
函数调用
JavaScript 函数有 4 种调用方式。
每种方式的不同方式在于 this 的初始化。
一般而言,在Javascript中,this指向函数执行时的当前对象。
作为一个函数调用
function myFunction(a, b) { return a * b; } myFunction(10, 2); window.myFunction(10, 2);
以上函数不属于任何对象。但是在 JavaScript 中它始终是默认的全局对象。
在 HTML 中默认的全局对象是 HTML 页面本身,所以函数是属于 HTML 页面。
在浏览器中的页面对象是浏览器窗口(window 对象)。以上函数会自动变为 window 对象的函数。
myFunction() 和 window.myFunction() 是一样的:
函数作为方法调用
var myObject = { firstName:"John", lastName: "Doe", fullName: function () { return this.firstName + " " + this.lastName; } } myObject.fullName(); // 返回 "John Doe"
对象 (myObject), 对象有两个属性 (firstName 和 lastName), 及一个方法 (fullName):
函数作为对象方法调用,会使得 this 的值成为对象本身。
使用构造函数调用函数
如果函数调用前使用了 new 关键字, 则是调用了构造函数。
这看起来就像创建了新的函数,但实际上 JavaScript 函数是重新创建的对象:
// 构造函数: function myFunction(arg1, arg2) { this.firstName = arg1; this.lastName = arg2; } // 创建个新的对象,新对象会继承构造函数的属性和方法 var x = new myFunction("John","Doe"); x.firstName;
构造函数中 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 的值, 且作为已存在对象的新方法调用。
全局对象
当函数没有被自身的对象调用时, this 的值就会变成全局对象。
在 web 浏览器中全局对象是浏览器窗口(window 对象)。
function myFunction() { return this; } myFunction(); // 返回 window 对象
注意: 函数作为全局对象调用,会使 this 的值成为全局对象。 |