目标:
- 能够说出函数的多种定义和调用方式
- 能够说出和改变函数内部this的指向
- 能够说出严格模式的特点
- 能够把函数作为参数和返回值传递
- 能够说出闭包的作用
- 能够说出递归的两个条件
- 能够说出深拷贝和浅拷贝的区别
1. 函数的定义和调用
1.1 函数的定义方式
<script>
// 函数的定义方式
// 1. 自定义函数(命名函数)
function fn() { };
// 2. 函数表达式 (匿名函数)
var fun = function () { };
// 3. 利用 new Function('参数1','参数2', '函数体');
var f = new Function('a', 'b', 'console.log(a+b)');
f(1, 2);
// 4. 所有函数都是 Function 的实例(对象)
console.dir(f);
console.log(f instanceof Object); //true instanceof属于
// 5. 函数也属于对象
</script>
Function
里面参数都必须是字符串格式- 第三种方式执行效率低,也不方便书写,因此较少使用
- 所有函数都是
Function
的实例化对象 - 函数也属于对象
Function
方式效率低,操作麻烦,作了解
函数也属于对象,同样有原型对象,原型链:
1.2 函数的调用方式
- 普通函数:直接加括号,
fn()
- 对象的方法:加小数点方式,
obj.fn()
- 构造函数:
new
构造函数 - 绑定事件函数:触发相应事件,例如
click
点击触发函数 - 定时器函数:
setInterval
,每隔一段时间调用函数 - 立即执行函数:
(function() {})()
,自动调用,直接执行
<script>
// 1. 普通函数:直接加括号,fn() !!this 指向window
function fn() {
console.log('美丽人生');
}
fn(); //或 fn.call();
// 2. 对象的方法:加小数点方式, obj.fn() !!this指向的是对象 o
var o = {
sayHi: function () {
console.log('美丽人生');
}
}
o.sayHi();
// 3. 构造函数:new 构造函数 !!指向 ldh 这个实例对象 原型对象里面的this 指向的也是 ldh这个实例对象
function Star() { };
new Star();
// 4. 绑定事件函数:触发相应事件,例如 click 点击触发函数 !!this 指向的是函数的调用者 btn这个按钮对象
btn, onclick = function () { }; //点击了按钮就可以调用
// 5. 定时器函数:setInterval,每隔一段时间调用函数 !!this 指向的也是window
setInterval(function () { }, 1000); //这个函数是定时器自动1秒调用一次
// 6. 立即执行函数:(function() {})(),自动调用,直接执行 !!this还是指向window
(function () {
console.log('美丽人生');
})(); //自动调用,直接执行
</script>
2. this
2.1 函数内 this 的指向
调用方式 | this 指向 |
---|---|
普通函数 | window |
构造函数 | 实例对象,原型对象里面的方法也指向实例对象 |
对象的方法 | 该方法所属对象 |
绑定事件函数 | 绑定事件对象 |
定时器函数 | window |
立即执行函数 | window |
2.2 改变函数内部 this 指向
JavaScript 为我们专门提供了一些函数方法来帮我们更优雅的处理函数内部 this
的指向问题,常用的有 bind()
、call()
、apply()
三种方法。
2.2.1 call
call()
方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this
指向。
fun.call(thisArg, arg1, arg2, ...);
参数说明:
thisArg
:在fun
函数运行时指定的this
值arg1
,arg2
:传递的其他参数- 返回值就是函数的返回值,因为它就是调用函数
- 因此当我们想改变
this
指向,同时想调用这个函数的时候,可以使用call
,比如继承
<script>
// 改变函数内this指向 js提供了三种方法 call() apply() bind()
// 1. call()
var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a + b);
}
fn.call(o, 1, 2);
// call 第一个可以调用函数 第二个可以改变函数内的this 指向
// call 的主要作用可以实现继承
function Father(uname, age, sex) {
this.uname = uname;
this.age = age;
this.sex = sex;
}
function Son(uname, age, sex) {
Father.call(this, uname, age, sex);
}
var son = new Son('刘德华', 18, '男');
console.log(son);
</script>
2.2.2 apply
apply()
方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的 this
指向。
fun.apply(thisArg, [argsArray])