一、函数的定义
1、function 关键字
function fn(){}
2、函数表达式(匿名函数)
var fn = function(){}
3、new Function()
var f = new Function('a', 'b', 'console.log(a + b)');
f(1, 2);
var fn = new Function('参数1','参数2'..., '函数体')
注意
/*Function 里面参数都必须是字符串格式
这种方式执行效率低,也不方便书写,因此较少使用
所有函数都是 Function 的实例(对象)
函数也属于对象
*/
二、函数的调用
/* 1. 普通函数 */
function fn() {
console.log('人生的巅峰');
}
fn();
/* 2. 对象的方法 */
var o = {
sayHi: function() {
console.log('人生的巅峰');
}
}
o.sayHi();
/* 3. 构造函数*/
function Star() {};
new Star();
/* 4. 绑定事件函数*/
btn.onclick = function() {}; // 点击了按钮就可以调用这个函数
/* 5. 定时器函数*/
setInterval(function() {}, 1000); // 这个函数是定时器自动1秒钟调用一次
/* 6. 立即执行函数(自调用函数)*/
(function() {
console.log('人生的巅峰');
})();
三、函数内部的this指向问题
不同类型的函数,内部的this指向是不同的,而且调用方式的不同决定了this指向的不同,但一般来说this是指向函数的调用者。
四、改变this的指向
1、call()
使用 函数.call(对象,参数1,参数2…) 的方法来调用一个函数,可以改变函数的this指向,让函数的this指向参数里的那个对象。还可以通过该方法实现继承。
// 案例代码
var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this.name);
console.log(a+b)
};
fn(1,2)// 此时的this指向的是window 运行结果为 undefined、3
fn.call(o,1,2)// 此时的this指向的是对象o,参数使用逗号隔开,运行结果为andy、3
2、apply()
使用 函数.apply(对象,[参数1,参数2…]) 的形式来调用一个函数,也可以改变函数的this指向,但此时参数必须以数组的形式传递。可以结合数学内置对象来实现获取数字数组的最大最小值。
// 案例代码
var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a+b)
};
fn(1,2)// 此时的this指向的是window 运行结果为undefined、3
fn.apply(o,[1,2])//此时的this指向的是对象o,参数使用数组传递 运行结果为andy、3
// 结合数学内置对象实现求数字数组的最大值
var arr = [1,66,3,99,4]
var max = Math.max.apply(Math,arr)
3、bind()
函数bind(对象,参数1,参数2…)方法可以能只改变函数的this指向,而不调用这个方法,并有返回值,是原函数改变this后产生的新函数。
// 案例代码
var o = {
name: 'andy'
};
function fn(a, b) {
console.log(this);
console.log(a + b);
};
var f = fn.bind(o, 1, 2); //此处的f是bind返回的新函数
f();//调用新函数 this指向的是对象o 参数使用逗号隔开andy、3
4、call()、apply()、bind()的异同
共同点:
三者都属于Function.prototype上的方法,每个function实例都有这三个方法,而且都可以通过方法的第一个参数来改变函数内部的this指向。
不同点:
① call 和 apply 在改变函数内部this指向的同时,会调用函数。而bind 不调用函数,只改变函数的this指向。
② call 和 bind 传递的参数都是用逗号隔开的独立参数,而apply是以数组的形式来传递参数。
③ 应用场景:call 经常来实现继承,apply 经常是来操作数组、bind用来不调用函数,只改变函数this指向。
五、高阶函数
所谓的高阶函数 就是指一个函数的内部对其他函数进行操作,接受函数作为参数或者将函数作为返回值,此时该函数就是一个高阶函数。
六、闭包(了解)
闭包(closure)是指有权访问另一个函数作用域中变量的函数,简单来说就是,一个作用域可以访问另一个函数作用域的局部变量。闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
我理解的闭包就是"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包的主要作用就是:延伸函数局部变量的作用范围。
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
// 案例代码
// 1.利用闭包的方式得到当前li 的索引号
for (var i = 0; i < lis.length; i++) {
// 利用for循环创建了4个立即执行函数
// 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它的i这变量
(function(i) {
lis[i].onclick = function() {
console.log(i);
}
})(i);
}
// 2.闭包应用-3秒钟之后,打印所有li元素的内容
for (var i = 0; i < lis.length; i++) {
(function(i) {
setTimeout(function() {
console.log(lis[i].innerHTML);
}, 3000)
})(i);
}
详细内容请参考 http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html