函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块,在JS中定义函数的方式有两种:函数声明和函数表达式。git
区分函数声明和表达式最简单的方法是看function关键字出如今声明中的位置(不单单是一行代码, 而是整个声明中的位置)。若是function是声明中的第一个词,那么就是一个函数声明,不然就是一个函数表达式。github
// 函数声明
function f1() {
//
}
// 函数表达式
var f2 = function () {
//
}
// 函数表达式
(function () {
//
})()
复制代码
函数声明会提高,但函数表达式不会。声明提高在执行上下文。数组
function f() {
console.log(1);
}
f(); // 1
var f = function () {
console.log(2);
}
f(); // 2
复制代码
由于函数声明会提高,因此不能非函数的代码块中声明函数,好比if。网络
// 下面代码的原始意图是不声明函数f,可是因为f的提高,致使if语句无效,因此上面的代码不会报错
if (false) {
// 这样声明由于if不是块级做用域,那么函数会提高,不论if如何判断f()都会生效
function f1() {
console.log(1);
}
}
f1(); // 1
// 要达到在条件语句中定义函数的目的,只有使用函数表达式
if (false) {
var f2 = function () {
console.log(2);
}
}
f2(); // TypeError: f2 is not a function
复制代码
但我在测试时发现新版火狐、Chrome、IE11都不会在if中提高函数声明,但IE11如下版本会,因此为避免出错,尽可能在if等非函数代码块中使用函数表达式。app
函数传递参数函数
JS中全部函数的参数都是按值传递的。学习
var a = 1;
function f1(arg) {
arg = 2;
console.log(arg); //2,参数若是是基本类型是按值传递,传递的是参数的副本,操做不影响原变量
}
f1(a);
console.log(a); // 1
var obj = {
a: 1
};
function f2(arg) {
arg.value = 2;
console.log(arg.value); //2,传递对象的时候,传递对象的引用的副本,改变参数会改变原参数
}
f2(obj);
console.log(obj.a) // 2
var obj2 = {
value: 1
};
function f3(arg) {
arg = { // 函数内部重写参数,这下变量引用的就是一个局部变量
a: 2
};
console.log(arg.a); //2,传递引用参数副本,可是又从新给参数赋值,切断原来的引用,因此原有引用为改变
}
f3(obj2);
console.log(obj2.a) // 1
复制代码
函数属性测试
函数属性包括:length和prototypethis
length,函数的length属性是只读属性,函数定义时的形参个数即一般也是函数调用时指望传入函数的参数个数。spa
function add(a, b) {
return a + b;
}
add.length // 2,函数声明时形参长度
复制代码
prototype,每一个函数都包含一个prototype属性,这个属性是指向一个对象的引用,这个对象称为“原型对象”。每一个函数都包含不一样的原型对象。当函数用作构造函数时,新建立的对象会从原型对象上继承属性。
函数内部属性:arguments和this
arguments,arguments是一个类数组对象,包含传入函数的全部参数,arguments的主要用途是保存函数参数。
function add(a, b) {
return arguments[0] + arguments[1];
}
add(1, 2); // 3
复制代码
this,this引用的是函数据以执行的环境对象,关于this请点这里this
var a = {
name: 'a',
sayName: function () {
console.log(this.name);
}
};
a.sayName(); // 'a'
复制代码
函数方法
每一个函数都包含两个非继承而来的方法:apply()和call()。这两个方法的用途都是在特定的域中调用函数,其真正强大之处在于可以扩充函数赖以运行的做用域,ES5又新增bind()方法。
关于apply、call和bind请点这里this
由于函数也是对象,因此函数也有toString()方法,返回函数的字符串形式。
匿名函数
函数声明必需要有标识符名称,但函数表达式能够不写标识符,这样的函数称为匿名函数。
// 匿名函数赋值给变量
var f = function () {
//
}
// 匿名函数自执行,自执行后内部声明的局部变量和函数会被销毁
(function () {
//
})()
// 匿名函数不会自执行,会报错,这是由于这是一个函数声明,函数声明后边不能跟圆括号,函数表达式后边能够跟圆括号
function () {
//
}()
复制代码
写在最后:
我只是一个自学JS的初学者,笔记是学习时各处收集的,有一些是我本身的理解。可是很多知识来自分享到网络的大神们,由于实在不知道我在哪里使用了谁的文章,因此只能统一的表达一下个人感谢! 文章里边可能有的地方会有错误,若是发现,能够留言提醒我。