首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如果你没有用var声明它或者它不是参数,为什么在函数的某些情况下不改变全局变量?

这个问题涉及到JavaScript中的变量作用域和函数作用域的概念。在JavaScript中,变量的作用域分为全局作用域和函数作用域。全局作用域中的变量可以在整个程序中被访问和修改,而函数作用域中的变量只能在函数内部被访问和修改。

当在函数内部使用一个变量时,JavaScript会首先在函数作用域中查找该变量,如果找不到,则会继续在全局作用域中查找。如果在全局作用域中也找不到,则会抛出一个错误。

在函数内部,如果使用了一个未声明的变量,则会默认创建一个全局变量。这是因为在函数作用域中没有找到该变量,因此JavaScript会在全局作用域中创建一个新的变量。

如果在函数内部使用了一个已经声明的全局变量,则会修改全局变量的值。这是因为在函数作用域中找到了该变量,因此会直接修改该变量的值。

如果在函数内部使用了一个未声明的变量,并且使用了var关键字声明,则会在函数作用域中创建一个新的变量。这是因为使用了var关键字,因此该变量的作用域被限制在函数作用域中,不会影响全局作用域中的变量。

因此,如果在函数内部使用了一个未声明的变量,并且不使用var关键字声明,则会默认创建一个全局变量。这是因为在函数作用域中没有找到该变量,因此JavaScript会在全局作用域中创建一个新的变量。如果该变量是一个参数,则不会创建全局变量,因为在函数作用域中已经找到了该变量。

总之,在函数内部使用未声明的变量时,需要注意变量的作用域和作用域链的概念,以避免意外创建全局变量。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

「译」JavaScript 究竟是如何工作?(第二部分)

内存堆 image.png Orinoco logo:V8 垃圾回收器 每当你 JavaScript 程序中定义了一个变量、常量或者对象时,都需要一个地方来存储。这个地方就是内存堆。...下面是一些会导致程序出现内存泄漏常见错误: 全局变量如果不断地创建全局变量,不管有没有用到它们,它们都将滞留在程序整个执行过程中。如果这些变量是深层嵌套对象,将会浪费大量内存。...var a = { ... } var b = { ... } function hello() { c = a; // 这是一个没有意识到全局变量 } 如果试图访问一个此前没有声明变量...递归可以大幅度地减少执行算法所花费时间(时间复杂度),不过理解和实施较为复杂。 下面的例子中,基本事件永远不会执行,lonley 函数没有返回值情况下不断地调用自身,最终会导致栈溢出。...事件循环就是用来发挥这个作用。 事件循环 到现在为止,我们谈到内容大多包含在 V8 里面,但是如果去查看 V8 代码库,会发现并不包含例如 setTimeout 或者 DOM 实现。

49810

JavaScript 闭包详解

闭包函数可以访问[包裹其函数]内各种参数和变量,即便外部函数已经执行完毕.(至于为什么请看下文)....一、为什么要闭包 使外部得以访问函数内部变量; 避免全局变量使用,防止全局变量污染(匿名函数); 让某些关键变量得以常驻内存,免于被回收销毁(闭包函数); ---- 二、让某些变量得以常驻内存 我们需要将立即执行函数与闭包结合...,直到确认子函数不会再被调用(子函数被删除或者失去指针)为止; 类比一下,如果学过webpack的话,应该会知道webpack在打包一个文件时候会把这个文件依赖所有文件一起打包,就是为了防止使用时候出问题...; 可见立即执行函数保存变量时泛用性比普通函数强; 三、让外部得以访问函数内变量 外部访问函数内变量跟立即执行函数没什么必然关系,不使用立即执行函数也可以进行保存,上面说到结合立即执行函数写法只是针对某些特殊情况下无法依据需求保存变量问题...引擎发现用一个小括号结束了函数,觉得这是错.

43020
  • 56 道高频 JavaScript 与 ES6+ 面试题及答案

    首先,所有的全局变量都是 window 属性,语句 var a = 1; 等价于 window.a = 1; 可以用如下方式来检测全局变量是否声明:"变量名称" in window。...澄清一下,函数声明是如下这样代码: function functionName(arg1, arg2){ //函数体 } 如下不是函数,而是函数表达式,相当于变量赋值: var functionName...null 典型用法是: 作为函数参数,表示该函数参数不是对象。 作为对象原型链终点。 当声明变量还未被初始化时,变量默认值为 undefined。...情况四:apply 调用 apply() 是函数对象一个方法,作用是改变函数调用对象,第一个参数就表示改变调用这个函数对象。因此,this 指就是这第一个参数。...所以,如果把父函数当作对象(object)使用,把闭包当作公用方法(Public Method),把内部变量当作私有属性(private value),这时一定要小心,不要随便改变函数内部变量

    90240

    56 道高频 JavaScript 与 ES6+ 面试题及答案

    首先,所有的全局变量都是 window 属性,语句 var a = 1; 等价于 window.a = 1; 可以用如下方式来检测全局变量是否声明:"变量名称" in window。...澄清一下,函数声明是如下这样代码: function functionName(arg1, arg2){ //函数体 } 如下不是函数,而是函数表达式,相当于变量赋值: var functionName...null 典型用法是: 作为函数参数,表示该函数参数不是对象。 作为对象原型链终点。 当声明变量还未被初始化时,变量默认值为 undefined。...情况四:apply 调用 apply() 是函数对象一个方法,作用是改变函数调用对象,第一个参数就表示改变调用这个函数对象。因此,this 指就是这第一个参数。...所以,如果把父函数当作对象(object)使用,把闭包当作公用方法(Public Method),把内部变量当作私有属性(private value),这时一定要小心,不要随便改变函数内部变量

    1.1K10

    es6中Let和Const详解

    某些实现可能不报错),是因为参数x默认值等于另一个参数y,而此时y还没有声明,属于“死区”。...使用let声明变量时,只要变量还没有声明完成前使用,就会报错。上面这行就属于这个情况变量x声明语句还没有执行完成前,就去取x值,导致报错”x 未定义“。...// 不会报错,各个块级作用域之间不互相影响 不能在函数内部重新声明参数。...不过,对于引用类型而言的话,并不会对象内容不变,而是对象地址不变。也就是说,可以修改对象内部成员,但是不可以修改该变量地址。...// undefined 上面代码中,全局变量a由var命令声明,所以它是顶层对象属性;全局变量b由let命令声明,所以它不是顶层对象属性,返回undefined。

    54930

    ES6语法学习(let与var区别、块级作用域、const命令)

    console.log(i); } } a[6]();//6 思考:如果每一轮循环变量i都是重新声明,那么怎么知道上一轮循环值从而进行计算出本轮循环值呢?...例1:下面的代码中,存在全局变量tmp,但是块级作用域中let又声明了一个全局变量tmp,导致后者绑定这个块级作用域,所以let声明变量之前,对tmp赋值就会报错 var tmp = 123;...例:下面的函数中有两个代码块,都声明了变量n,运行后输出5,这表示外层代码块不受内层代码块影响,如果使用var定义变量n,最后输出值就是10 function f1() { let...下面两种函数声明ES5中都是非法,但是浏览器没有遵守这个规定,为了兼容以前旧代码,还是支持了块级作用域中声明函数,因此下面两种情况实际上都能运行,并不会报错。...但是对于引用类型数据(对象、数组),变量指向内存地址保存只是一个指针,const只能保证这个指针是固定,至于指向数据结构是不是可变这是不能控制,因此,将一个对象声明为常量时需要非常小心。

    1K00

    我们是80后 golang入坑系列

    Golang当中,本地定义是按照函数或者语义块来区分。只要在一个函数中定义变量,或者一个语义块中定义变量都是本地变量。...与本地变量相对应就是全局变量。 只要是函数外部定义都属于全局变量。...因为我们说过变量声明方式有“var"和”:="两种。如果不小心写了个" g:=a+b"。虽然对最终结果没有影响,但意思已经改变了,变成了main函数中重新创建了一个g变量。...虽说全局变量也是变量,但全局变量声明只能通过var来实现。...参数变量可以声明之后不使用。这点尤为明显,如果声明了一个本地变量,但自始至终都没有用到。编译时会提示删除这个变量。而参数变量,无论函数内部有没有用到,都不会提示。

    62870

    浏览器内存泄漏场景、监控以及分析

    意外全局变量 全局变量生命周期最长,直到页面关闭前,都存活着,所以全局变量内存一直都不会被回收 当全局变量使用不当,没有及时回收(手动赋值 null),或者拼写错误等将某个变量挂载到全局变量时...遗漏 DOM 元素 DOM 元素生命周期正常是取决于是否挂载 DOM 树上,当从 DOM 树上移除时,也就可以被销毁回收了 但如果某个 DOM 元素, js 中也持有引用时,那么生命周期就由...这个能看到内容很少,比较简单,目的也很明确,就是一段时间内,都有哪些操作申请内存,且用了多少 总之,这些工具并没有办法直接给你答复,告诉 xxx 就是内存泄漏元凶,如果浏览器层面就能确定了,那它干嘛不回收...是吧,即使周期性调用 replaceThing 函数函数局部变量 o 即使存储着上个全局变量 t 值,但毕竟是局部变量,函数执行完毕,如果没有外部持有引用,也就可以被回收掉了,所以最终内存就只剩下全局变量...,与最开始区别就在于,至少 unused 函数执行后,就可以释放掉而已 其实,这里应该考虑代码有没有问题,为什么需要局部变量存储,为什么需要 unused 函数存在,这个函数目的又是什么,如果只是为了将来某个时刻用来判断上个全局变量

    3.4K41

    JavaScriptIIFE(即时执行方法)

    假设有一个需求,每次调用函数,都返回加1一个数字(数字初始值为0) 【1】全局变量   一般情况下,我们会使用全局变量来保存该数字状态 var a = 0; function add(){ return...这是因为javascript代码解释时,当遇到function关键字时,会默认把当做是一个函数声明,而不是函数表达式,如果没有把显视地表达成函数表达式,就报错了,因为函数声明需要一个函数名,而上面的代码中函数没有函数名...以上便是立即执行函数+闭包作用。 我为什么更愿意称它是“立即执行函数”而不是“自执行函数” IIFE称谓现在似乎已经得到了广泛推广(不知道是不是原文作者功劳?)...{ arguments.callee(); };   // 这可能也算是个自执行匿名函数,但仅仅是foo标志引用它自身 // 如果将foo改变成其它将得到一个used-to-self-execute...// 该函数返回一个对象,包含要暴露属性 // 如下代码如果不使用立即执行函数,就会多一个属性i // 如果有了属性i,我们就能调用counter.i改变i值 // 对我们来说这种不确定因素越少越好

    1.4K50

    Javascript 严格模式详解

    4.1 全局变量显式声明 正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。...某些情况下,只允许静态绑定。也就是说,属性和方法到底归属哪个对象,在编译阶段就确定。这样做有利于编译效率提高,也使得代码更容易阅读,更少出现意外。 具体来说,涉及以下几个方面。..."use strict";   var o = {     p: 1,     p: 2   }; // 语法错误 (2)函数不能有重名参数 正常模式下,如果函数有多个重名参数,可以用arguments..."use strict";   var n = 0100; // 语法错误 4.8 arguments对象限制 arguments是函数参数对象,严格模式对使用做了限制。...为了与新版本接轨,严格模式只允许全局作用域或函数作用域顶层声明函数。也就是说,不允许函数代码块内声明函数

    1.2K80

    Javascript 严格模式 “use strict”

    4.1 全局变量显式声明 正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。...某些情况下,只允许静态绑定。也就是说,属性和方法到底归属哪个对象,在编译阶段就确定。这样做有利于编译效率提高,也使得代码更容易阅读,更少出现意外。 具体来说,涉及以下几个方面。...”use strict”;   var o = {     p: 1,     p: 2   }; // 语法错误 (2)函数不能有重名参数 正常模式下,如果函数有多个重名参数,可以用arguments...”use strict”;   var n = 0100; // 语法错误 4.8 arguments对象限制 arguments是函数参数对象,严格模式对使用做了限制。...为了与新版本接轨,严格模式只允许全局作用域或函数作用域顶层声明函数。也就是说,不允许函数代码块内声明函数

    95810

    记住,永远都不要在 Flutter 中使用全局变量

    全局变量似乎是很棒 Flutter 程序组件,因为它们被声明一次并且可以被程序中每个函数访问。...以上所有原因都说明了为什么 Flutter 中永远不应该使用全局变量。...如果删除一个全局变量,则必须搜索整个程序并重构每个有权访问已删除全局变量函数。 2. 全局变量使单元测试变得痛苦 如果更改了一个具有全局变量模块,那么将不得不为下一次测试重置。...全局变量导致“面条”代码 由于程序中每个函数都可以修改全局变量,因此很难跟踪更改。如果正在构建一个大型应用程序, Flutter 中使用全局变量情况会升级。...但是,有些开发人员会使用全局变量,因为他们一个小团队中,并且某些情况下不利于更改。 但是,无论应用程序大小如何,当需要维护代码时,全局变量都会带来挑战。

    3.5K30

    【C语言】变量

    要区分变量名和变量值是两个不同概念。         ② 变量顾名思义是可以发生改变,当你定义一个变量时候值,到后面你想改变值还是可以发生改变。        ...② 变量声明一般情况下会有两种情况。 需要建立存储空间。 int a = 0;//声明定义时候就已经建立了存储空间 不需要建立存储空间。...局部变量  概述一个函数内部声明变量是内部变量,函数内部有效。函数之外是不能使用,这样变量就是局部变量。         某个函数或块内部声明变量称为局部变量。...概述函数外部声明就是全局变量全局变量是定义函数外部,通常是程序顶部。...全局变量整个程序生命周期内都是有效,在任意函数内部能访问全局变量全局变量可以被任何函数访问,也就是说全局变量声明后整个程序中都是可用

    15510

    React 语法之let和const命令

    变量bar用let命令声明,不会发生变量提升。这表示声明之前,变量bar是不存在,这时如果用到,就会抛出一个错误。...function bar(x = y, y = 2) { return [x, y]; } bar(); // 报错 上面代码中,调用bar函数之所以报错(某些实现可能不报错),是因为参数x默认值等于另一个参数...如果确实需要,也应该写成函数表达式,而不是函数声明语句。...ES6块级作用域允许声明函数规则,只使用大括号情况下成立,如果没有使用大括号,就会报错。...undefined 上面代码中,全局变量a由var命令声明,所以它是全局对象属性;全局变量b由let命令声明,所以它不是全局对象属性,返回undefined。

    6.4K60

    C++知识概要

    存储静态存储区,作用域仍为局部作用域,当定义函数或者语句块结束时候,作用域结束。...函数返回类型前加 static,函数就定义为静态函数函数定义和声明默认情况下都是 extern ,但静态函数只是声明文件当中可见,不能被其他文件所用。...) 派生类自己构造函数 必须使用成员列表初始化四种情况 当初始化一个引用成员时 当初始化一个常量成员时 当调用一个基类构造函数,而拥有一组参数时 当调用一个成员类构造函数,而拥有一组参数时...;clear()函数,只能清空内容,不能改变容量大小;如果要想在删除内容同时释放内存,那么可以选择 deque 容器 int main(){ vector vec(10, 0);...还可以采用通用算法 remove()来删除 vector 容器中元素 采用 remove 一般情况下不改变容器大小,而 pop_back()与 erase()等成员函数改变容器大小,使得之后所有迭代器

    1.1K20

    前端面试(2)javascript

    首先需要声明类,然后访问,否则像下面的代码会抛出一个 ReferenceError。...第二种场景,用来计数循环变量泄露为全局变量(前面重复声明中提到): //上面代码中,变量i只用来控制循环,但是循环结束后,并没有消失,泄露成了全局变量。...Javascript 语言特殊之处,就在于函数内部可以直接读取全局变量函数外部自然无法读取函数局部变量,函数内部声明变量时候,一定要使用 var 命令。...一共运行了两次,第一次值是 999,第二次值是 1000。这证明了,函数 f1 中局部变量 n 一直保存在内存中,并没有 f1 调用后被自动清除。 为什么会这样呢?...所以,如果把父函数当作对象(object)使用,把闭包当作公用方法(Public Method),把内部变量当作私有属性(private value),这时一定要小心,不要随便改变函数内部变量

    1.2K20

    如何使JavaScript更高效

    然而,因为某些原因,它可能会让脚本运行缓慢。 首先,如果代码函数或另一个作用域中引用全局变量,脚本引擎会依次通过每个作用域直到全局作用域。局部变量找起来会快得多。...如果需要对某个元素或者子元素进行改变,而且这些改变又不能合并在一个单独重绘中,那就可以先设置这个元素样式为 display:none,然后改变,再把设置为普通显示状态。...{ // … } } } 避免遍历 DOM 时候进行修改 对于某些类型 DOM 集合,如果脚本在这些集合中检索时候改变了相关元素,集合会立即发生变化而不会等你脚本运行结束...如果某个引用保存在当前文档全局变量中,或者保存在某个长期存在对象属性中,通过将其设置为 null,或者通过 delete 来清除。...某些情况下,并不希望出现一条额外历史记录,因为用户不需要回到之前页面。如果在内存特别重要环境下,这样做就非常有用。

    1.6K10

    JavaScript工作原理:内存管理+如何处理4个常见内存泄漏

    读取与写入可能是写入一个变量或者一个对象属性值,甚至传递函数参数。 Release when the memory is not needed anymore 大多数内存管理问题都在这个阶段。...换句话说,GC 是不可预测,无法确定何时会执行收集。这意味着某些情况下,程序使用内存要比实际需要还多。另一个场景是,特别敏感应用中,那么一些短暂暂停会显得特别明显。...但是,如果不使用 var声明,则会创建一个冗余全局变量。在上述情况下,这不会造成太大伤害。肯定可以想象一个更具破坏性场景。...如果必须使用全局变量来存储数据,请确保使用完成后将其指定为null或重新分配。 2....当这种情况发生时,就会保留同一 DOM 元素两份引用:一个 DOM 树中,另一个字典中。如果将来某个时候决定要删除这些行,则需要让两个引用都不可达。

    85751

    JavaScript工作原理:内存管理+如何处理4个常见内存泄漏

    读取与写入可能是写入一个变量或者一个对象属性值,甚至传递函数参数。 Release when the memory is not needed anymore 大多数内存管理问题都在这个阶段。...换句话说,GC 是不可预测,无法确定何时会执行收集。这意味着某些情况下,程序使用内存要比实际需要还多。另一个场景是,特别敏感应用中,那么一些短暂暂停会显得特别明显。...但是,如果不使用 var声明,则会创建一个冗余全局变量。在上述情况下,这不会造成太大伤害。肯定可以想象一个更具破坏性场景。...如果必须使用全局变量来存储数据,请确保使用完成后将其指定为null或重新分配。 2....当这种情况发生时,就会保留同一 DOM 元素两份引用:一个 DOM 树中,另一个字典中。如果将来某个时候决定要删除这些行,则需要让两个引用都不可达。

    80930
    领券