JavaScript之函数(函数声明与this指向)

// 函数声明的几个方式
// 标准的函数声明
function func1 () {
    console.log(123);
};
// 函数的表达式
let func2 = function() {
    console.log(456);
}
// 构造函数与函数表达式
let func3 = new Function(console.log(789));
// 对象中的方法
let obj = {
    name:'xuwen',
    fun4() {
        console.log('aaa');
    }
}

// 函数提升
{
    // 函数与变量一样  在执行前就提升  并且把整个函数提升
    // 在es6之前   变量的可以重复声明  就会出现函数与变量重名的情况  这是不对的   在es6中   声明过的名称不可重复 不管是函数名还是变量名
    func4();
    function func4 () {
        console.log('func4');
    };
}


{
    // 经典函数  递归函数
    // 经典实例  阶乘
    function factorial(num){
        if(num > 0) {
            if(num == 1){
                return 1;
            }
            return num * factorial(--num);
        }else{
            console.error(参数错误);
        }
    }
    console.log(factorial(10));  // 3628800
    // 使用递归求和
    function sum(...args) {
        return args.length == 0 ? 0 : args.pop() + sum(...args);   // pop()返回值为删除的元素  即数组的尾元素
    }
    console.log(sum(1,2,3,4,5,6));  // 21
}
{
    // this 指向
    // this遵循谁调用就指向谁    如果没有特别指出就是指向全局环境   在浏览器中指向window  在node环境在指向当前模块{}
    console.log(this);    //  {}
    const obj = {
        name:'xuwen',
        say(){
            console.log(this.name);
        },
        run(){
            console.log([...this.name].map(function(item) {
                return item + `-${this.name}`;
            }));
        },
        run1(){
            console.log([...this.name].map(item =>  item + `-${this.name}`));
        }
    };
    obj.say();     // xuwen    说明指向声明的对象
    obj.run();  //  因为当前模块并没有name属性  索引该属性为undefined
    // [
    //     'x-undefined',
    //     'u-undefined',
    //     'w-undefined',
    //     'e-undefined',
    //     'n-undefined'
    //   ]

    //  如果使用使用箭头函数 this则指向父级的上下文环境
    obj.run1();   // [ 'x-xuwen', 'u-xuwen', 'w-xuwen', 'e-xuwen', 'n-xuwen' ]


    // 有时候我们需要特别把this指向特定的元素    通过改变this指向改变元素的属性   比如  数组指向伪数组从而达到伪数组具备数组的方法
    //   call  apply  bind  这三个方法就是干这个事的
    // call 与 apply 主要区别为参数不一样   call  从第二个参数开始 单独传参  不限参数  不限类型   而apply第二个参数为数组  
    const s1 = new Set([1,2,3]);
    [].push.call(s1,4,6);
    console.log(s1);  // Set { 1, 2, 3, '0': 4, '1': 6, length: 2 }
    [].push.apply(s1,[7,8]);
    console.log(s1);   // Set { 1, 2, 3, '0': 4, '1': 6, '2': 7, '3': 8, length: 4 }
    // bind 传参类似call   但 bind 是不会立即执行的  返回一个改变了this指向的函数
    let s2 = [].push.bind(s1,9);
    console.log(s2());   // 5   返回length属性的值
}

你可能感兴趣的