js函数执行机制

709 阅读4分钟
        function fn(){

        }
        var f = function qqq(){
            
        }
        console.dir(f);
        var f2 = ()=>{
            //没有this 和 arguments

        }

js中的函数:

  • function加函数名的函数
  • 函数表达式(函数表达是里面function后边也可以加函数名,但是是没有意义的)
  • 自执行函数,没有函数名,只能执行一次
       (function () {
            console.log(this, 1);
        })();
        ! function () {
            console.log(this, 2);
        }();
        ~ function () {
            console.log(this, 3);
        }();
  • ES6箭头函数

函数定义时候写在括号里的参数是形参,函数执行时传进去的参数是实参,形参和实参是一一对应的,arguments 实参集合 类数组(元素集合) return 决定函数的返回值 打断函数执行 this 函数的执行主体(非严格模式下,形参和arguments有映射关系,但在严格模式下却没有)

函数的存储过程

js中的函数属于引用数据类型数据,因此,函数存储是:开一个16进制的对内存,把函数体内的代码当字符串存进去

函数的执行

函数执行,开一个私有作用域(栈内存),把对内存的代码字符串拿出来执行,先形参赋值,在变量提升,然后代码从上到下执行(执行上下文),函数执行完,变量销毁,作用域销毁.

变量提升

在代码执行之前 js会把代码中 带var 和带 function 的提前声明,带var的只声明不定义,带function的声明又定义.变量提升,只提升等号左边的内容,对于条件句来说,无论条件是否成立都会进行变量提升,在条件句和循环句中的function是只声明不定义的

作用域(scope)

作用域是代码执行时起作用的区域 ,作用域就是一块栈内存(栈内存是用来存储值类型数据的,还有就是提供代码运行环境)

  • 全局作用域

    页面一打开就会形成一个全局作用域,一个页面只有一个全局作用域,也即是window,也是执行上下文context,在全局作用域声明的变量称为全局变量

  • 私有作用域

    函数执行的时候会形成一个私有作用域,私有作用域中声明的变量 称为私有变量 ;形参也是私有变量

  • 块级作用域

    判断句 循环句 的大括号包起来的部分 es6新增 只有let 和 const 声明的变量能识别块级作用域,对于var 来说不存在块级作用域这一说

上级作用域:函数执行时形成的那个私有作用域 ,一般都会存在一个上级作用域,私有作用域的上级作用域是谁,跟这个函数在哪执行没有关系,只跟函数在那个作用域 定义的 有关系

作用域链(scope chain)

私有作用域中的变量 可能不是该私有作用域的私有变量,这时 该变量对应的值 就需要去上级作用域查找,若仍不是上级作用域的私有变量,则接着向上级查找 ,直到查找到window(全局)位置 ,若仍然没有,则会报错; 上述查找变量的机制 我们称为作用域链

var let const 三者区别

  • var 可以重复声明 let 和 const 不可以
  • var 存在变量提升 let 和 const 没有
  • var声明的变量会在window 下增加一个对应的属性;let 和const 不会
  • var 不识别块级作用域 let 和const可以识别

闭包(closure)

闭包首先是一个不销毁的作用域,用来保护变量,存储值 利用闭包 可以实现模块化开发 闭包不能多用:多用会导致内存泄漏;用途:模块化发开时候,为了避免命名冲突使用闭包

一个闭包里面的东西只能自己访问使用,别人访问不了 例如:
        var sum = function(){
            var a = 200;
            return function(){
                console.log(a);
            }
        }

堆、栈内存的销毁

堆内存的销毁

  • 谷歌浏览器 :定时清除,每隔一段时间就会通篇销毁一次 把js中没有被用到的地址销毁
  • 火狐浏览器 :计数清除,根据当前地址的引用个数来决定这个是否要被销毁

栈内存的销毁

  • 全局作用域的销毁:只有当页面关闭时才会销毁
  • 私有作用域的销毁:只要函数的返回值是引用数据类型,那么这个作用域就不会被销毁;

高阶函数

// var f = a=>b=>c=>a+b+c;
// f(1)(2)(3);
var f = a=>{
    return b=>{
        return c=>{
            return a+b+c;
        }
    }
}
f(1)(2)(3);

函数中的this

this 就是函数的执行主体

  • 箭头函数中没有this 和 arguments;它是吧这两者当普通变量去对待了;箭头函数中this 是指向了 上级作用域中的this ,arguments也一样
  • 事件绑定中的this 就是当前绑定的元素
  • 自执行函数中的this 是window
  • 定时器中的this也是window

this的指向是谁 可以通过看点的方式来确定,函数执行 点 的前边是谁,this就是谁,没点就是window