javascript权威指南——函数篇

203 阅读2分钟

函数

函数是这样的一段javascript代码,它只定义一次,点可能被执行或调用任意次。

关键词解释

  • 参数(行参:函数中定义的变量;实参:调用函数时传入的参数);
  • 调用上下文:普通函数——this(对象调用,this则为方法上级的对象;直接调用,为window);箭头函数——this为当前作用域的顶级对象。
//exam 1
var obj ={
    a:1,
    fn:function(){
        console.log(this.a)
    }
}
var a = 2;

obj.fn()  // 1
var m = obj.fn
m() // 2
//exam 2
var obj={
    a:1,
    b:2,
    c:{
        a:3,
        fn:()=>{
            console.log(this.a)
        },
        fn2:function(){
            console.log(this.a)
        }
    }
}
var a =4
obj.c.fn()    //4
obj.c.fn2()   //3

浏览器解析的时候,二者都会发生变量提升(hoisting),会将a变量提升为undefined,aaa会被当成函数提升,当代码从第一行开始执行之后,a被覆盖成console.log(1);

PS:变量提升是浏览器编译器的行为。

  • 函数表达式/函数声明式
//函数表达式
var a = function(){console.log(1)};

//函数声明式
function a(){console.log(2)};

a() // 1

  • arguments(实参对象):是一个类数组对象,具有数字下标这样可通过数字访问他(数字下标),具有length属性,但并不是数组,不具备数组方法,例如pop,push;
    //argument转换成数组
    function arg2arr(){
        //第一种
        let arr = Array.prototype.slice.call(arguments)
        //第二种
        let arr2 = Array.from(arguments)
        //第三种
        let arr3 = [...arguments]
        console.log(arr,arr2,arr3);
    }

测试截图:

  • 闭包:函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学文献中称为“闭包”。

阮一峰老师的解释,恰当的形容了这句晦涩难懂的定义:获取函数内部变量的函数,称为闭包。

特点:

  1. 变量存贮在内存中,不会被浏览器垃圾策略清除;
  2. 获取内部变量;
  3. 存在内存泄漏的问题;
  • prototype属性:这个属性是指向一个对象的引用,这个对象称作“原型对象”。每一个函数都包含不同的原型对象。当将函数用作构造函数的时候,新创建的对象会从对象上继承属性。

  • call/aplly方法:看做是某个对象的方法,通过调用方法的形式来间接调用函数。

f.call(thisObj,arg1,arg2,arg3...)
f.apply(thisObj,[arg1,arg2,arg3...])
  • bind方法:(ES5方法)将函数绑定至某个对象;
    function add (x,y,z){
        return x+y+z
    }
    var succ = add.bind({x:1},2)
    succ(3);//6

    //重写一个bind方法
    Function.prototype.bind = function(thisTarget){
        this.apply(thisTarget,[...arguments])
    }

PS:犀牛书晦涩难懂的一段

github原文地址