如何定义函数作用域的新作用域

时间:2021-07-17 21:00:41

标签: javascript function variables scope

我想知道是否有办法为函数局部 [[Scopes]] 定义变量,例如以下函数

//Parent function has a global scope {Window}
function x() {
  //Local variable, closure to function {x}
  var a = 123;
  //Local function which have access to all {x} local scope like {a}
  function y() {
    console.log(a)
  }
   //Check the function y scope {window, Closure(x){a=123}
  console.dir(y)
}
x()

Scopes 上面的函数应该是这样的

0: Closure (x) {a: 123}
1: Global {window: Window, self: Window, document: docume...

可以访问 window object 和它的父 closures 就像 a

使用 Scopes 时具有 3 eval() 的局部函数的另一个示例

//Parent function has a global scope {Window}
function s(obj, fn) {
  //Local variable and closure to {s} function
  var q = 123
  if (typeof fn === 'function') {
    /*
     - {y} here is local function which before {eval} have 2 scope
    - {window}, closure (s) {obj: {a: "a", b: "b", c: "c"}, q = 123}

    - after using of eval it's will get a new scope {block} scope Which will allow this function to access everything like obj, fn, y itself, q everything inside the parent function not just a Closure scope for things used on it like {q} and also it's will change 
     * closure (s) {obj: {a: "a", b: "b", c: "c"}, q = 123}
     - to 
     * closure (s) {arguments: Arguments(2) [{…}, ƒ, callee: ƒ, Symbol(Symbol.iterator): ƒ], fn: ƒ (), obj: {a: "a", b: "b", c: "c"}, q: 123, r: 989
     - the new closure will add everything even if it's not used on {y}

    */
    function y(a) {
        console.log(obj.a, q)
    }
    //That's will add a new scope to function {y} and change closure scope of it
    eval('var r = 989')
    //check {y} scope
    console.dir(y)
  }
}
s({
  'a': 'a',
  'b': 'b',
  'c': 'c'
}, function() {console.log('i am a global function')})

上面的函数 y 可以访问 x 参数、变量、块,如 y 函数 Scope 上面的函数将是这样

0: Block (s) {defVar: ƒ}
1: Closure (s) {obj: {…}, q: 123, arguments: Arguments(2), fn: ƒ, defVar: ƒ, …}
2: Global {window: Window, self: Window, document: docume...

但是如果我有以下功能

//global function
//scrope = {window}
function x(fn) {
  var q = 123;
  //here's i want to define q var a local scope of {fn} 
  //like fn['[[Scopes]]']['1'] = 'Closure (x) {q: 123}' so when calling q from {fn} it's will return the q value i want to define it with the same name not like argument
  console.log(fn())
};
//global function
//scrope = {window}
//i want to allow var q of {x} function to be used inside this function normally like 
//function(){var t = "i'am a global function"; return t, q }
//the example above will return Uncaught ReferenceError: q is not defined
x(function(){var t = "i'am a global function"; return t, q })

上面的 2 个函数将在全局作用域 window 中,所以有没有办法添加新的作用域来运行 fn['[[Scopes]]']['1'] = 'Closure (x) {q: 123}'fn['[[Scopes]]']['1'] = x['[[Scopes]]']['1'] 我知道 [[Scopes]] 不能可以作为属性访问,但这只是示例

另一个例子

// i want to do here the same at comments in example above
function x(fn) {
  var q = 123;
  y()
};
function y(){return 'str'}

有没有办法从函数 y 中为函数 x 设置新的闭包,例如 y['[[Scopes]]']['1'] = {a = 123, b = 456}

我想要做的就是将局部变量设置为另一个函数的函数或允许全局函数访问另一个函数的函数

  • 最后一个例子更清楚
  • 以下函数选择带有显示键值的 html 元素
  • 我想在使用可选函数时访问selectElements方法中声明的变量或将其定义为可选函数
<块引用>

HTML

<nav>
    <ul class="nav-items">
        <li class="nav-active"><a href="/">Home</a></li>
        <li class="nav-item"><a href="#nav-active">Fruits</a></li>
        <li class="nav-item"><a href="#nav-inactive">Veggies</a></li>
    </ul>
</nav>
 function selectElements(obj, fn) {
      var sel = {
        'class': function(el, arg) {
          if (arg) {
            return document.getElementsByClassName(el)
          } else {
            return 'document.getElementsByClassName("'+el+'")'
          }
        },
        'id': function(el, arg) {
          if (arg) {
            return document.getElementById(el)
          } else {
            return 'document.getElementById("'+el+'")'
          }
        },
        'tag': function(el, arg) {
          if (arg) {
            return document.getElementsByTagName(el)
          } else {
            return 'document.getElementsByTagName("'+el+'")'
          }
        }
      }
      if (typeof fn === 'function') {
        var closureHanlder, text = ''
        //console.dir(fn, defVar)
        for(var i in obj) {
          obj[i].replace(/^\./, function(elem) {
            elem = obj[i].replace(/^\./, '');
            elem = sel.class(elem);
            text += 'var ' + i + ' = ' + elem + ';\n'
          }).replace(/^\#+/, function(elem) {
            elem = obj[i].replace(/^\#/, '');
            elem = sel.id(elem);
            text += 'var ' + i + ' = ' + elem + ';\n'
          }).replace(/^\w+/, function(elem) {
            if (!elem.startsWith('undefined')) {
              elem = sel.tag(elem)
              text += 'var ' + i + ' = ' + elem + ';\n'
            }
          })
        }
        console.log(text)
        //decalre the elements with variables name 
        eval(text)
        console.log(nav, navActive, navItem, navContainer)
        // i want this function to get the declared elements as local variables or access them from this function {selectElements}
        fn()
      }
    }
    var el = {
      'nav': 'nav',
      'navActive': '.nav-active',
      'navItem': '.nav-item',
      'navContainer': '.nav-items'
    }
    selectElements(el, function () {
      //here i want to access those varibles 
      //console.log(nav, navActive, navItem, navContainer)
      // as a local varibles or access them from the function wheich used on it 
    })

1 个答案:

答案 0 :(得分:0)

据我所知,你不能。对于初学者来说,[[Scopes]] 不是任何 function 对象的标准内部插槽,也不是任何对象的标准内部插槽。因此,您充其量只会寻找适用于 Chrome 的解决方案,而它肯定无法通过 javascript 获得。

这里也没什么可收获的。该函数不知道您将哪些其他变量包含在其作用域中。如果您希望添加一个恒定的作用域,那么它也没有任何意义,因为您只需将相应的声明添加到相应的函数中即可。

这就是 with 未能提供任何实际价值的原因,同时也让您怀疑是否有任何标识符也被新的动态上下文所掩盖。