JavaScript函数


JavaScript 函数是通过 function 关键词定义的,既可以使用函数声明也可以使用函数表达式


函数声明
function functionName(parameters) {
    要执行的代码
}

// 实例
function myFunction(a, b) {
     return a * b;
}

// 分号用于分隔可执行的JavaScript语句
// 由于函数声明不是可执行的语句,以分号结尾并不常见

函数表达式
// JavaScript 函数也可以使用表达式来定义,函数表达式可以在变量中存储:
var x = function (a, b) {
    return a * b
};

// 上述函数其实是一个匿名函数,存放在变量中的函数不需要函数名,它们总是使用变量名调用,其使用分号结尾是因为它是可执行语句的一部分

// 在变量中保存函数表达式之后,此变量可用作函数
var z = x(4,3)

函数的提升

提升(Hoisting)是JavaScript 将声明移动到当前作用域顶端的默认行为

Hoisting 应用于变量声明函数声明

正因如此,JavaScript函数能够在声明之前被调用:

myFunction(5);

 function myFunction(y) {
     return y * y;
}

注意:使用表达式定义的函数不会被提升


函数是对象

JavaScript 中的 typeof 运算符会为函数返回 “function”。

但是最好是把 JavaScript 函数描述为对象,因为 JavaScript 函数都有属性和方法。



自调用函数

函数表达式可以作为“自调用”

自调用表达式是在不进行调用的情况下,自动被调用的

假如表达式后面跟着(),函数表达式会自动执行

你无法对函数声明进行自调用,需要在函数周围添加括号,以指示它是一个函数表达式:

(function () {
    var x = "Hello!"
})()

箭头函数
// ES5
var x = function(x,y) {
    return x*y;
}

// ES6
const x = (x,y) => x*y;

/*
箭头函数没有自己的 this,它们不适合定义对象方法。

箭头函数不会被提升,所以它们必须在使用前进行定义。

使用 const 比使用 var 更安全,因为函数表达式始终是常量值。

如果函数是单个语句,则只能省略 return 关键字和大括号。但是,保留它们是一个好习惯:
*/

const x = (x,y) => {return x * y};

// 注意:IE11或更早的版本不支持箭头函数

函数参数

函数参数(parameter)指的是在函数定义中列出的名称

函数参数(argument)指的是传递到函数或由函数接收到的真实


参数规则

  • JavaScript 函数定义不会为参数(parameter)规定数据类型;

  • JavaScript 函数不会对所传递的参数(argument)实行类型检查;

  • JavaScript 函数不会检查所接收参数(argument)的数量


参数默认:

  • 如果调用参数时省略了参数(少于被声明的数量),则丢失的值被设置为:undefined
  • 如果函数调用的参数太多(超过声明),则可以使用 arguments 对象来获取这些参数
    • JavaScript 函数有一个名为 arguments 对象的内置对象
    • arguments 对象包含函数调用时使用的参数数组
    • arguments.length 会返回函数被调用时收到的参数数目

JavaScript函数Call和apply

方法重用:使用call()方法,可以编写能够在不同对象上使用的方法


函数是对象方法

在JavaScript中,函数是对象的方法

如果一个函数不是JavaScript 对象的方法,那么它就是全局对象的函数


JavaScript call()方法

call()方法是预定义的JavaScript方法,它可以让你使用属于另一个对象的方法

var person = {
    fullName: function() {
        return this.firstName + " " + this.lastName;
    }
}
var person1 = {
    firstName:"Bill",
    lastName: "Gates",
}
var person2 = {
    firstName:"Steve",
    lastName: "Jobs",
}

// 调用person的fullname方法,并用于person1

person.fullName.call(person1);  // 将返回 "Bill Gates"

带参数的call()方法

call()方法可以接受参数

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}

var person1 = {
  firstName:"Bill",
  lastName: "Gates"
}

person.fullName.call(person1, "Seattle", "USA");

JavaScript aplly()方法

apply() 方法与 call() 方法非常相似

var person = {
    fullName: function() {
        return this.firstName + " " + this.lastName;
    }
}
var person1 = {
    firstName: "Bill",
    lastName: "Gates",
}
person.fullName.apply(person1);  // 将返回 "Bill Gates"

call()和apply()之间的区别

call() 方法分别接受参数。

apply() 方法接受数组形式的参数。

如果要使用数组而不是参数列表,则 apply() 方法非常方便。

带参数的apply()方法

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}

var person1 = {
  firstName:"John",
  lastName: "Doe"
}

person.fullName.apply(person1, ["Oslo", "Norway"]);

与call()方法对比

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"John",
  lastName: "Doe"
}
person.fullName.call(person1, "Oslo", "Norway");

闭包

JavaScript变量属于局部或全局作用域

全局变量能够通过闭包实现局部(私有)

注意:不通过关键词 var 创建的变量总是全局的,即使它们在函数中创建


变量的生命周期

全局变量活得和应用程序(窗口、网页)一样久

局部变量活得不长。它们在函数调用时创建,在函数完成后被删除


JavaScript嵌套函数

所有函数都有权访问全局作用域,事实上,在 JavaScript 中,所有函数都有权访问它们“上面”的作用域

JavaScript 支持嵌套函数,嵌套函数可以访问其上的作用域,例如:

// 内部函数 plus() 可以访问父函数中的 counter 变量

function add() {
    var counter = 0;
    function plus() {counter += 1;}
    plus();     
    return counter; 
}

add() // 将返回1

JavaScript闭包

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();

add();
add();
add();

// 计数器目前是 3 

// 变量 add 的赋值是自调用函数的返回值。

// 这个自调用函数只运行一次。它设置计数器为零(0),并返回函数表达式。

// 这样 add 成为了函数。最“精彩的”部分是它能够访问父作用域中的计数器。

// 这被称为 JavaScript 闭包。它使函数拥有“私有”变量成为可能。

// 计数器被这个匿名函数的作用域保护,并且只能使用 add 函数来修改。

// 闭包指的是有权访问父作用域的函数,即使在父函数关闭之后。

闭包的更多介绍

http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

https://www.cnblogs.com/itjeff/p/10106855.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值