函数相关

141 阅读2分钟

函数内部this的指向

调用的方式不同,决定了this的指向不同。

调用方式                      this指向
普通函数调用                   window
构造函数调用                   实例对象,原型对象里方法中的this也指向实例对象
对象方法调用                   该方法所属对象
事件绑定方法                   绑定事件对象
定时器函数                     window
立即执行函数                   window

改变函数内部this的指向

常用的有call()、apply()、bind()三种方法

call方法

1、call可以调用函数,改变函数内的this指向,参数形式用逗号隔开

let people = {
    name: '刘德华'
}
function fn(a, b, c) {
    console.log(this); // this指向的是people
    console.log(a, b, c)
}
fn.call(people, 1, 2, 3);

2、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);
}
let son = new Son('刘德华', 18, '男');
console.log(son); // 实例对象继承了父类构造函数的属性

apply方法

apply可以调用函数,改变函数内的this指向(),参数以数组的形式

let people = {
    name: '刘德华'
}
function fn() {
    console.log(this); // this指向的是people
}
fn.apply(people, ['apple', 'banana']);

利用apply求值

let arr = [10, 2, 45, 77, 60]; let max = Math.max.apply(null, arr);
let min = Math.min.apply(null, arr);
console.log(max);
console.log(min);

bind方法

bind方法不会调用函数,但会改变函数内部this的指向,返回由指定的this值和初始化参数的原始拷贝

let people = {
    name: '刘德华'
}
function fn() {
    console.log(this); // this指向的是people
}
let f = fn.bind(people);
f()

Example:

<button>点击</button>
let btn = document.querySelector('button');
btn.onclick = function () {
    this.disabled = true;    // 方法一,外部保存this
    // let self = this;
    // setTimeout(function() {
    //     // this.disabled = false;  // 错误: 定时器函数里的this,指向的是window
    //     self.disabled = false;
    // }, 3000);

    // 方法二,利用bind,修改定时器函数里的this
    // setTimeout(function() {
    //     this.disabled = false;
    // }.bind(this), 3000);

    // 方法三,利用箭头函数
    // setTimeout(() => { 
    //     this.disabled = false;
    // }, 3000);
};

call、apply和bind的总结

相同点:都可以改变函数内部this的指向

区别点:

1、call和apply会调用函数,并且改变函数内部this的指向

2、call和apply传递的参数不一样,call传递参数aru1, aru2,...的形式;apply必须数组形式

3、bind不会调用函数,参数跟call一样

主要应用场景:

1、call经常做继承

2、apply经常更数组有关系,比如接触数学对象实现数组的最大值、最小值

3、bind不调用函数,改变this指向,比如改变定时器内部的this指向

递归函数

利用递归求阶乘,1*2*3*4...*n

function fn(n) {
    if (n == 1) return 1;
    return n * fn(n - 1);
}
console.log(fn(9));

利用递归求斐波那契数列,0、1、1、2、3、5、8、13、21、34、……这个数列从第3项开始,每一项都等于前两项之和

function fb(n) {
    if (n == 1 || n == 2) return 1;
    return fb(n - 1) + fb(n - 2);
}
console.log(fb(9));

面向对象编程的相关知识点