通过 “函数对象”看javascript函数

145 阅读3分钟

#前言

本文主要阐述一些JavaScript行为的深层原因。很多东西都是主观臆测结合编程经验推测出来的。 如有谬误请包涵,也可以联系作者(qq:504451056,email:504451056@qq.com)

javascript的行为

scope函数对象

所谓的scope就是引擎在执行函数定义(包括函数声明,定义函数表达式,与匿名函数声明)时,向内存堆申请内存空间并把函数的上下文写入改空间。以后函数将在该上下文执行。该上下文包涵2部分:
  • (1) 声明部分
  • (2) 执行部分

声明部分:
包涵:
声明的内部函数,变量,参数,维护一个地址池,地址池里面的地址指向内部函数,变量和参数。
本质:就是函数对象的属性
执行部分:
包涵:
除了声明以外的计算过程都包含在这个里面
本质:就是函数对象的一个方法
参数部分
在调动函数部分时动态赋值

引擎发现下面这个函数声明

function funOut(arg,arg1){
    var prop = 0;
    function funInner(){
        console.log(porp1);
    }
    var props = 1;
    funInner();
    console.log(arg,arg1);
}

总体经历了以下几步

1创建scope对象并创建地址池
    var funOut = {
        arg:null,
        arg1:null,
        prop:null,
        prop1:null,
        funInner:null,
        _props_:window,
        init:function(supperContext,arg,arg1){
            funOut. _props_ = supperContext||windows
            funOut.arg = arg,
            funOut.arg1=arg1,
            funInner = function(funOut,arg,arg1){
                funOut.arg = arg,
                funOut.arg1=arg1
            },
        },
        applay:function(){
            prop = 0;
            porp1 = 1;
            funInner();
            console.log(arg,arg1);
        },
       this:windows//因为funOut对用户不可见,this只是一个特殊的处理而已
    } 
    注:上面这个结构是引擎通过引擎内置语言实现的,对用户不可见,有可能是C也有可能是汇编这个不是重点

函数中的this

正如scope所示,scope对用户不可见的所以this不可能提供给用户。所以function 中的this是一个伪this,直接为了保持和window的联系直接提供了windowd的地址。 同事修改function中的this有几种方法如下:
  • bind()
  • apply()
  • .
  • call()
  • =>

变量提升

    其实到现在变量提升原因已经很明显了,函数对象不是js对象遵循其他编程语言规范

作用域链本质

所谓的作用域链是对scope对象链的代称,该链跟js原型链有曲艺同工之妙,只要有末端节点就可以向上冒泡寻访所有节点这是嵌套函数本质

函数调用栈问题

通过前面知道 函数对象在堆中,那么栈中放的必然是地址信息。注意时间循环对函数结束的影响
function cir(){
    cir()
}

function cor(){
    setTimeOut(function(){
        cor
    },2000);
    return true;//cor函数执行到此处已经完结,弹出栈所以cor的深度是固定的
}
注意两则的本质区别 

函数柯里化本质

函数柯里化本质就是返回 作用域的末端,可以理解为一条作用域链的末端,好处在于可以创建支链,切可以方便移动。

以上东西很多为个人臆测。如果有指导更正感激不尽!