3 种函数定义方式:
1, 使用关键字 function 来声明并定义函数
- function myFunction(a, b) {
- return a * b;
- }
调用函数:
var x = myFunction(4, 3);
2, 使用关键字 function 来定义匿名函数
function (a, b) {return a * b}
匿名函数可赋值给变量或者自调用:
匿名函数赋值给变量:
- var x = function (a, b) {return a * b};
- var z = x(4, 3);
匿名函数自调用:
- (function (a, b) {
- return a * b;
- })(4,3);
3, 使用 Function() 构造函数来定义函数
var myFunction = new Function("a", "b", "return a * b");
调用函数:
var x = myFunction(4, 3);
注意:
提升 (Hoisting) 是 JavaScript 默认将当前作用域中的变量声明与函数声明提升到前面去的的行为.
上述 3 种函数定义方式中第一种方式声明了函数, 因此, 函数可以在声明之前调用:
- myFunction(5);
- function myFunction(y) {
- return y * y;
- }
4 种函数调用方式:
函数调用方式的区别在于调用函数时 this 的初始化不同.
this 是 JavaScript 语言的一个关键字, 它代表函数运行时, 自动生成的一个内部对象, 只能在函数内部使用.
函数使用的场合不同, this 的值也不同. 但是有一个原则: this 代表的是调用函数的那个对象.
1, 作为全局函数 (全局对象方法) 被调用
- function myFunction(a, b) {
- return a * b;
- }
- myFunction(10, 2); // myFunction(10, 2) 返回 20
- window.myFunction(10, 2); // window.myFunction(10, 2) 返回 20
在 html 中默认的全局对象是 HTML 页面本身, 所以函数是属于 HTML 页面.
在浏览器中的全局对象是浏览器窗口(window 对象), 以上函数会自动变为 window 对象的方法. myFunction() 和 window.myFunction() 是一样的.
函数作为全局函数被调用时, this 的值为全局对象.
注意: 全局变量, 方法或函数容易造成命名冲突的 bug, 而且使用 window 对象作为一个变量容易造成程序崩溃.
2, 作为对象方法被调用
- var myObject = {
- firstName:"John",
- lastName: "Doe",
- fullName: function () {
- return this.firstName + " " + this.lastName;
- }
- }
- myObject.fullName(); // 返回 "John Doe"
fullName 函数是一个对象方法, 属于 myObject 对象.
函数作为对象方法被调用时, this 的值为它所属的对象.
- var myObject = {
- firstName:"John",
- lastName: "Doe",
- fullName: function () {
- return this;
- }
- }
- myObject.fullName(); // 返回 [object Object] (所有者对象)
3, 作为构造函数被调用
在 JavaScript 中, 构造函数用于创建新的对象. 调用构造函数需要在前面添加 new 关键字.
- // 构造函数
- function myFunction(arg1, arg2) {
- this.firstName = arg1;
- this.lastName = arg2;
- }
- // 调用构造函数创建新的对象
- var x = new myFunction("John","Doe");
- x.firstName; // 返回 "John"
新对象会继承构造函数的属性和方法.
构造函数中的 this 关键字没有任何的值.
函数作为构造函数被调用时, this 的值为构造函数所实例化的对象.
4, 使用函数方法调用
在 JavaScript 中, 函数是对象, 函数也有属性和方法.
call() 和 apply() 是预定义的函数方法, 我们可以使用这两个方法来调用函数.
call() 和 apply() 两个方法的第一个参数必须是对象本身.
- function myFunction(a, b) {
- return a * b;
- }
- myObject = myFunction.call(myObject, 10, 2); // 返回 20
- function myFunction(a, b) {
- return a * b;
- }
- myArray = [10, 2];
- myObject = myFunction.apply(myObject, myArray); // 返回 20
两个方法都使用了对象本身作为第一个参数. 两者的区别在于第二个参数: apply 传入的是一个参数数组, 也就是将多个参数组合成为一个数组传入, 而 call 则作为 call 的参数传入(从第二个参数开始).
在 JavaScript 严格模式 (strict mode) 下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象.
在 JavaScript 非严格模式 (non-strict mode) 下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代.
通过 call() 或 apply() 方法你可以设置 this 的值, 且作为已存在对象的新方法调用.
来源: https://www.cnblogs.com/lalong/p/9359203.html