当前位置: 首页 > Web前端 > HTML

javascriptscope

时间:2023-03-28 00:44:08 HTML

scope简单的说,scope是指程序中定义变量的区域,它决定了当前正在执行的代码对变量的访问权限。在ES5中,一般只有两种作用域类型:全局作用域:作为程序的最外层作用域,全局作用域一直存在于函数作用域中:函数作用域只有在定义函数时才会被创建,并且会被包含在父函数作用域或全局作用域中。看看这段代码:vara=100functiontest(){varb=a*2vara=200varc=a/2console.log(b)console.log(c)}test()//这里会打印什么?分析:1、首先这段代码形成了一个全局作用域和一个函数作用域。2.全局作用域中有一个变量a,其赋值为1003。在测试函数作用域中定义了局部变量b、a、c4。这里有变量Ascension,在函数作用域内,先进行变量提升varb;变种;变种C;5.然后给b赋值。此时a还没有被赋值,所以a的值是undefined,然后a*2,所以b就是NaN6。然后给a赋值200,给a/2赋值c等于100,所以最终会打印出NaN,100在ES6中,新增了一个块级作用域。简单的说,花括号{...}里面的区域是块级作用域,但是Javascript本身并不支持块级作用域,需要使用ES6提出的let和const来创建块级作用域//ES5if(true){varname='Nanjiu'}console.log(name)//Nanjiu//ES6if(true){letage=18}console.log(age)//errorscopechain会在这里报错当可执行文件代码内部访问变量,会先查找当前作用域下是否有这样的变量,则立即返回,如果没有,则去父作用域查找...总能找到全局作用域。我们将这种作用域的嵌套机制称为作用域链。词法范围是范围的工作模型。词法作用域是JavaScript中使用的一种作用域。词法作用域也可以称为静态作用域。所谓词法作用域,是你写代码的时候写变量和作用域的地方决定的,也就是词法作用域是静态作用域,是你写代码的时候决定的。函数的范围取决于它声明的位置,与实际调用的位置无关。MDN对闭包的定义:一个函数和它周围(词法环境)的引用捆绑在一起(或者函数被引用包围),这样的组合就是一个闭包(closure),即闭包允许你访问范围它的外部功能在内部功能中。在JavaScript中,无论何时创建一个函数,都会在创建该函数的同时创建一个闭包。我们可以得出:closure=function+outerscope先看代码:varname='FrontendNanjiu'functionsay(){console.log(name)}say()分析:say函数可以访问变量a在外部范围内,所以这不形成一个闭包吗?书中有这样一句话《Javascript权威指南》:严格来说,所有的JavaScript函数都是闭包,但这只是理论上的闭包,和我们平时使用的不一样。上面的例子只是一个简单的闭包。ECMAScript对闭包的定义:理论上:所有的函数都是闭包。因为它们在创建的时候就已经保存了上层上下文的数据。从实用的角度来说:闭包应该满足两个条件:1、代码中引用了外作用域的变量;2.即使创建它的上下文已经被破坏,它仍然存在;让我们看另一段关于《JavaScript权威指南》的代码://这里返回什么?很多同学可能会认为是全局作用域,但是真的是这样吗?我们来看看它的执行过程:1.首先执行全局代码,创建全局执行上下文,定义全局变量作用域并赋值2.声明checkscope函数,并创建函数的执行上下文,创建一个局部变量作用域并赋值3.声明f函数,创建函数的执行上下文4.执行checkscope函数,返回一个f函数并将其赋值给变量s5。执行s函数,相当于f函数被执行了。这里返回的范围是本地范围。至于为什么是局部作用域,我们在上面提到了词法作用的基本规则:JavaScript函数是使用定义它们的作用域来执行的。在定义f函数的作用域中,变量scope的值是局部作用域闭包的应用闭包。闭包的大部分应用都是在维护内部变量的上下文中使用的。由于闭包的存在,闭包可能会导致变量常驻内存,使用不当会导致内存泄漏。内存泄漏可能会导致应用程序冻结或崩溃。高频闭包面试题vararr=[]for(vari=0;i<3;i++){arr[i]=function(){console.log(i)}}arr[0]()//3arr[1]()//3arr[2]()//3//这里我变成了3//使用闭包求解vararr=[]for(vari=0;i<3;i++){arr[i]=(function(i){returnfunction(){console.log(i)}})(i)}arr[0]()//0arr[1]()//1arr[2]()//2