二. 函数进阶
2.1 函数的创建方式
函数声明
1
2
3function fn () {
// 函数体
}函数表达式
1
2
3var fn = function () {
// 函数体
};区别
- 预解析时,函数声明创建的函数整体会提升到所在执行环境【作用域】的顶部。
- 预解析时,函数表达式创建的函数,仅仅提升变量名到所在执行环境【作用域】的顶部。
2.2 函数本身也是对象
函数创建的第三种方式:
语法:
var 变量名 = new Function(‘形参1’,’形参2’,….,’程序代码’);代码:
1
2
3
4var fn = new Function('a','b','alert(a + b);');
console.log(fn instanceof Function); // true
console.log(fn instanceof Object); // true
fn(10,20); // 调用函数
2.3 函数内this指向不同的场景
this到底指向谁,是由程序在执行的过程中决定的。以下是关于this指向情况的基本整理
普通函数调用时,this指向window。
1
2
3
4
5
6// 定义一个函数
function fn () {
console.log(this);
}
// 调用
fn(); // this→window构造函数调用时,this指向当前所创建的对象。
1
2
3
4
5
6
7
8// 构造函数
function Student (name, age) {
this.name = name;
this.age = age;
console.log(this);
}
var stu1 = new Student('张三', '李四'); // this →
当前所创建的这个学生实例对象对象的方法调用时,this指向方法所属的对象。
1
2
3
4
5
6
7
8
9
10
11
12
13// 构造函数
function Student (name, age) {
this.name = name;
this.age = age;
}
// 原型中的方法
Student.prototype.sayHi = function() {
console.log(this);
console.log( this === stu1);
};
var stu1 = new Student('张三', '李四');
stu1.sayHi(); // this → stu1事件绑定的方法,this 指向事件源
1
2
3
4
5
6// id为box的div元素对象
var box = document.getElementById('box');
// 为box注册事件
box.onclick = function () {
console.log(this);
};定时器函数,this指向window
1
2
3setInterval(function() { // 省略了window
console.log(this);
}, 500);
2.4 改变函数内的this指向【掌握】
为什么要改变this ?
例如:我们经常在定时器外部备份 this 引用,然后在定时器函数内部使用外部 this 的引用。改变this的方式:函数有三个方法可以改变内部的this:call、apply、bind。
call方法
语法:
函数名.call(thisArg[, arg1[, arg2[, …]]]);参数
- thisArg,在 函数运行时指定的 this 值。若传null或undefined,则函数内部this指向window
- arg1, arg2, …指定的参数列表
应用
① 借用构造函数。
② 借用其他对象中的方法。
1
2
3
4
5
6
7
8
9
10
11var obj = {
0: 100,
1: 200,
2: 300,
3: 400,
length: 4
}
// obj.push(500); // 报错 对象中不存在这个方法
// 借用数组的
Array.prototype.push.call(obj,500);
console.log(obj);
apply方法
语法:
函数名.apply(thisArg, [argsArray])参数:
- thisArg,在 函数运行时指定的 this 值。若传null或undefined,则函数内部this指向window
- argsArray,是一个数组,数组中存放函数调用时需要传入的实参。
应用:
和call方法一样,唯一不同的时,函数或方法被借用时,apply以数组的方式存放实参。
1
2
3var nums = [11,66,33,44,55,77,22];
var max = Math.max.apply(Math,nums);
console.log(max);
bind方法
语法:
var 变量 = 函数名.bind(thisArg,[, arg1[, arg2[, …]]]);参数:
语法:
var 变量名 = 函数名.call(thisArg[, arg1[, arg2[, …]]]);参数:
- thisArg,在 函数运行时指定的 this 值。若传null或undefined,则函数内部this指向window
- arg1, arg2, …指定的参数列表
应用:
和call使用方式一样,不一样的时,使用bind时,借用的函数不会被立即执行,而是返回一个新的函数,若要执行,需要自己调用。
1
2
3
4
5
6
7
8
9
10
11
12var obj = {
age: 18
};
// id为box的div元素对象
var box = document.getElementById('box');
// 为box注册事件
box.onclick = function () {
console.log(this.age);
}.bind(obj);
setInterval(function() {
console.log(this.age);
}.bind(obj), 500);
2.5 函数的其他成员【了解】
- arguments
- 实参集合
- caller
- 函数的调用者
- length
- 形参的个数
- name
- 函数的名称
1 | function fn(x, y, z) { |