JavaScript作用域和传参的问题 5C

function foo(){
function bar(a){
i = 3;
console.log(i)
}
for(var i = 0;i<10;i++){
bar(i);
}
}
foo()//结果是死循环
下面这段代码只是将foo的参数改了一下
function foo(){
function bar(i){
i = 3;
console.log(i)
}
for(var i = 0;i<10;i++){
bar(i);
}
}
foo()//结果是死10个3

想不明白??????

0

8个回答

第一段代码,内外部变量 i,是同一个,运行时每次都会赋值3,恒小于10。

function foo(){
    function bar(a){
        i = 3;  // 这里的i跟外面是同一个
        console.log(i)
    }
    for(var i=0; i<10; i++){
        bar(i);
    }
}

第二段代码,bar函数内的变量i,每次都赋值为3,所以才会输出10个3。

function foo(){
    function bar(i){
        i = 3;  // 这里的i是bar函数体内的,但每次都赋值3
        console.log(i)
    }
    for(var i=0; i<10; i++){
        bar(i);
    }
}
foo()
4
weixin_42374714
weixin_42374714 这个习惯很好,暂一个
12 个月之前 回复
CFW_CSDN
昵称已存在吗 都是解答同个问题,就这个代码格式整齐、清晰。
12 个月之前 回复

第一个代码中bar函数内没有声明i变量,在bar函数内使用的i是外层作用域中的循环变量i,循环变量每次都重新赋值为3当然死循环了。
只要用var在bar函数内声明自己的i变量就可以了,
var i = 3;

第二个代码中bar函数的参数名改成了i,就等同用var在bar函数内声明了自己的i变量

2

众所周知,js中变量的基本类型和引用类型保存方式是不同的,这也就导致变量复制时也就不同了。如果从一个变量向另一个变量复制基本类型的值时,会将前者的值克隆一个,然后将克隆的值赋值到后者,因此这两个值是完全独立的,只是他们的value相同而已。
你下面那个Function bar(i)找的是i的克隆,没有对i产生影响

1

js会提升局部变量作用域到函数的开头
所以你的第一个函数相当于这样子
function foo(){
var i

function bar(a){
    i = 3;
    console.log(i)
}

for(i = 0;i<10;i++){
    bar(i);
}

}
更改之后相当于这样
function foo(){
function bar(a){
a = 3;
console.log(a)
}

for(var i = 0;i<10;i++){
    bar(i);
}

}

1

JavaScript传递参数是按值传递的,基本类型的传递如同基本类型变量的复制一样

1

根据程序结构可知,作用链时window-foo-bar;
1.js变量的查询时沿着作用链进行查找的
2.变量会在方法结束时销毁
3.当作用域链中出现多个同名变量时,自己作用域中的变量优先级高
分析第一个函数:
foo作用域中有变量 i;
bar作用域中有变量 a,i
当程序执行时,它会沿着window-foo-bar链去查找变量i,由于在bar作用域中没有定义i(没有var i,i变量也没
有在形参中),所以它使用的是foo作用域中的i,所以程序每次赋值时,实际赋的是foo作用域中的i,因此出现
死循环。
而在第二段程序中,i变量出现在了bar的形参中,也就是相当于在bar作用域中创建了变量i,因此在window-foo-bar
链中查找是是给bar作用域中的变量赋值,而bar中的i在bar执行结束后就销毁了,与foo作用域中的i没有任何关系,而foo
循环中使用的是foo变量,因此循环十次。

0

关键要弄清楚参数传递意味着什么
在执行bar(i)的时候,实际上存在着一个隐式赋值,即 var 形参 = 你传的实参,所以在当第一次循环(i=0)时,
第一串代码的bar(i)实际上可以理解为:
bar(){
var a = 0;
i = 3;
console.log(i)
}
bar()
在执行i = 3会进行变量查找(查找i的声明),最近的i是在for循环中声明的,于是查找到的i就是for循环中的i,然后将i赋值为3,同时for循环中的i也是3,于是就是死循环了,而a其实只是个迷惑。
同样在第一次循环(i=0)时,第二串代码可以理解为:
bar(){
var i = 0 ;
i = 3;
console.log(i)
}
bar()
在执行i = 3会进行变量查找(i的声明),最近的i是在for循环中声明的,于是查找到的i就是bar中的i,然后将i赋值为3,而for循环的i并不受影响,因为他们不是一个i,所以for循环正常进行

0

function foo(){
function bar(a){
a= 3; // 将i改成a好理解一点
console.log(a)
}
for(var i = 0;i<10;i++){
bar(i);
}
}


0
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
JavaScript变量作用域和变量提升
在看别人代码时,发现一个问题,就是一个未在上面声明或者定义的变量,可以正常使用而且不报错,我双击变量名,编译器给我把同名的高亮之后,发现这个变量的定义是在使用的下方定义的,网上查询才得知这是JS变量的一个特性,叫做变量提升,下面,先从最熟知的开始去理解这个变量提升!!<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JavaScr
Javascript变量作用域、变量提升
Javascript变量、变量提升以及作用域 执行环境对js编程的重要性不容忽视,理解其执行的原理,将有效提升编程素养。
JavaScript页面传参
JavaScript页面传参JavaScript页面传参JavaScript页面传参
javascript:模块化以及块作用域
现在的前端,基本都是用模块化的方式来写代码了,也是,毕竟一个项目太多js文件的情况下,全局污染必定存在,而js又提供了闭包,能很好的避免污染的问题     作用域大家都知道,就比如一个匿名函数,内部定义了一个变量,而这个变量的作用域就是在这个函数中,在其他的函数中无法调用到这个变量,比较麻烦,不像java等语言一样,可以用class,于是,js要获得块级作用域就只能用刚刚说的闭包来处理了,代码模式...
javascript深入之词法作用域和动态作用域
作用域作用域是指程序源代码中定义变量的区域。作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。静态作用域与动态作用域因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的。让我们认真看个例子就
javascript中的this作用域详解——针对初学者
//#######针对一名初学者对this的指向问题的理解######### //1.全局的函数调用 function test(){ this.name="global this" console.log(this.name) } test(); //global this var name="global this" function test(){ console.
JavaScript词法作用域(你不知道的JavaScript)
JavaScript并不是传统的块级作用域,而是函数作用域! 一、作用域 1. JavaScript引擎在代码执行前会对其进行编译,在这个过程中,像var a = 2 这样的声明会被分解成两个独立的步骤: 第一步(编译阶段):var a 在其作用域中声明新变量。这会在最开始的阶段,也就是代码执行前进行。 第二步(运行阶段):a = 2 会查询变量a(LHS查询)并对其进行赋值。 2.
关于javascript的声明提前导致的作用域污染
在javascript中,我们通常可以使用如下两种方式定义函数: 方式一: var fun = function(){ //code }; 方式二: fun(){ //code } 由于javascript的"声明提前(hoiosting)",加载js代码后,方式二中fun被"提前",此时fun已经是一个Function;但是方式一种的fun在刚加载js时却是undefined,
关于js中的作用域和作用域链以及常见的问题和结果方法
js中作用域和作用域链的详解,以及常见的一不小心就出做错的小代码片段
JavaScript中的构造函数的作用域安全
在JS中,构造函数其实就是一个使用new操作符调用的函数,和普通函数的区别是函数名的首字母大写(不是强制规定)。当使用new调用时,构造函数内用到的this对象会指向新创建的对象实例: function Person(name,age,job){ this.name = name; this.age = age; this.job = job; } var perso...
javascript基础:函数传递参数的方式、参数数组、变量范围(变量作用域)
一、函数的2种参数传递方式 (1)传值:把变量的值传入函数,函数不会另外分配内存保存值,所以不会改变原始值,一般适用于传入 数字、布尔值、字符串。 (2)传地址:把变量保存的内存地址传入,如果在函数中改变了值,原始值也会被改变。用于传入对象、数组、函数、字符串对象。 实验 //带2个参数,返回值,a为传值方式,b为传地址方式 function
javascript面试题 变量声明 作用域 运算符优先级
此题是我出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多难只是因为大多面试者过于轻视他。题目如下:function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { alert...
var和let 以及js作用域问题
今天学习ES6 的时候发现了var 和 let 之间的不同。var a=[];for(var i=0;i&amp;lt;10;i++){   a[i]=funciton(){       console.log(i);   }; }a[6]();  //10for(var i=0;i&amp;lt;a.length;i++){  a[i]();  //0~9的输出}var a=[];for(let i=0; i&amp;...
JavaScript 变量作用域和声明提升
本博文参考 文章 《javascript设计模式和开发实践》变量作用域相信大家能理解,但是,命名提升?What is this?虽然有javascript开发经验,但是有些概念还是需要不断复习,特别是不常见的。一、变量作用域 说到这个概念,不有自主的想到this,scope 这两个关键字。JavaScript的this总是指向一个明确的对象,这个对象是在执行的时候动态绑定的。通俗的说就是谁调
JS经典小坑(坑主要在JS没有块级作用域)
js中有一个经典的函数赋值错误,这个问题和闭包问题相关,我们先来看一下这个案例吧。   var arr = []; for(var i=0;i&amp;lt;2;i++){ arr[i] = function(){ return i; } } console.log(arr[0]());这个结果是2,和你想的一样吗?  可能有不少新手会误以为是1。那么接下来解释一...
javascript传递参数
ECMAScript中所有函数的参数都是 按值传递的,也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量中一样。 访问变量有按值和按引用的两种 方式,而参数只能按值传递。 在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者就是arguments对象中的一个元素)。在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此...
Javascript 中 作用域、闭包与 this 指针
js 中的作用域,闭包的理解和运用,this 的理解和运用
简述JS作用域、作用域链和闭包
作用域 定义:一个变量的作用域是程序源代码中定义这个变量的区域。 全局变量拥有全局作用域,局部变量只有局部作用域。块级作用域: 在ES6 let变量声明出来之前,JS是没有块级作用域的概念的,函数内部定义的变量才是局部变量,具体见下面的代码var a=1; for(var i=0;i<10;i++){ var b= f(a); } function f(x){ return x;
JavaScript之安全作用域的构造函数(高级函数)
JavaScript是一种极其灵活的语言,具有多种使用风格。一般来说,编写JavaScript要么使用过程方式,要么使用面向对象方式。由于它具有动态性,这种语言还能使用更为复杂的模式。于是JavaScript也为高级函数提供了一些技巧。
js面试与笔试---理解 JavaScript 作用域和作用域链
任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。   1.  全局作用域(Global Scope)   在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:   (1)最外层函数和在最外层函数外面定义的变量拥有全局作用...
Js中arguments的使用、函数自调用、变量作用域、函数作为参数传入、函数作为返回值
1,arguments是一个比较特别的对象,每个函数中都有一个arguments,它接收函数传入的参数,以数组的形式存放在 arguments,可遍历 //1,需求:求任意数的最大值 function getMax(){ var Max = arguments[0]; //arguments接收传进来的参数,通过下标可以索引 for (i = 1;i&amp;lt...
JavaScript概念总结:作用域、闭包、对象与原型链
1 JavaScript变量作用域 1.1 函数作用域 没有块作用域:即作用域不是以{}包围的,其作用域完成由函数来决定,因而if /for等语句中的花括号不是独立的作用域。 如前述,JS的在函数中定义的局部变量只对这个函数内部可见,称之谓函数作用域。 嵌套作用域变量搜索规则:当在函数中引用一个变量时,JS会搜索当前函数作用域,如果没有找到则搜索其上层作用域,一直到全局作用
JavaScript关于作用域、作用域链和闭包的理解
作用域先来谈谈变量的作用域 变量的作用域无非就是两种:全局变量和局部变量。 全局作用域: 最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:<script> var outerVar = "outer"; function fn(){ console.log(outerVar); } fn();//res
原生js之理解作用域
谈到作用域,我们就能想到全局变量、局部变量等名词,接下来,我讲谈谈我对作用域的理解。 ES5中的作用域 ES5中,有两种作用域:函数作用域和全局作用域。 第一段代码: &amp;amp;amp;lt;script type=&amp;amp;quot;text/javascript&amp;amp;quot;&amp;amp;amp;gt; var a = 0; func(); function func() { var b = 1; consol...
JS 作用域和作用域链
1. 作用域 作用域就是代码的执行环境,全局执行环境就是全局作用域,函数的执行环境就是私有作用域,它们都是栈内存。 执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。 全局执行环境是最外围的一个执行环境。根据 ECMAS...
3.1 JS window对象&&document文档对象&&变量的作用域&&隐藏样式&&入口函数
window 对象可以省略alert() 方法 弹出警示框完整的写法 : window.alert(“执行语句”); window 对象 窗口 一般情况是可以省略的。 console 控制台输出一般用于测试 代码 作用 console.log() 普通 console.warn() 警告 console.error() 错误 document文档对象
JS中的作用域(一)-详谈
本篇文章在于详细解读JavaScript的作用域,从底层原理来解释一些常见的问题,例如变量提升、隐式创建变量等问题,在和大家一起交流进步的同时,也算对自己知识掌握的记录,方便以后复习   首先,直接捡干的来,JS作用域大致分为三部分:词法作用域、函数作用域/块作用域、闭包。   在传统的编译语言中,程序的源代码编译由三个步骤组成:词法分析、语法分析、代码生成。而JS属于动态语言,它的编译过程不...
理解 js的作用域
1.ES5中的作用域for(var i =0;i<10;i++){} console.log(i)js这段代码,你觉得会输出什么?答案是10,熟悉java的同学肯定有点诧异,为什么会这样呢?因为js还是不同与java的,在ES5中,只有全局作用域和函数作用域,并没有块作用域,当然我们可以实现块作用域的功能。看下面代码:(function(){ for(var i =0;i<10;i++){} })(
javascript作用域和闭包,this
全局作用域打开一个 js 文件,写了一行代码,这行代码所在的位置就会是全局作用域(global scope)。比如:var name = 'minigui'局部作用域全局作用域只有一个,在全局使用域里面定义的其它的作用域都被称为局部作用域(local scope)。局部作用域是由函数创建的,每个函数都会创建一个局部作用域。下面我创建了一个名字是 greet 的函数,在它里面声明了一个 name 变量
JavaScript中的变量作用域
在es5中变量作用域分为两种:全局变量,局部变量; 局部变量:写在函数体内部,其中函数中所传递的参数也是局部变量(小括号中的),仅在定义的部分能够使用; 全局变量:写在函数体外部的变量,其中在函数中使用但未用var声明的变量也是全局变量,可以在全局中任何部分使用; 下面是关于变量作用域的小案例: 全局变量 (1)直接声明 var a = 10; console.log(a) ...
深入理解JavaScript中的作用域、作用域链和闭包
作用域先来谈谈变量的作用域 变量的作用域无非就是两种:全局变量和局部变量。 全局作用域: 最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:&amp;lt;script&amp;gt; var outerVar = &quot;outer&quot;; function fn(){ console.log(outerVar); } fn();/...
js中this的作用域
在js当中有一个关键字叫做this。this指向的是当前函数的拥有者。下面举三个例子来说明this。 第一个例子:var pet = { words:'....', speak:function(){ console.log(this.words); console.log(this); } } pet.speak();**结果为:**3
JavaScript 变量及其作用域
1 变量声明 1.1 声明方式 JavaScript 有三种声明方式:var - 声明一个变量,可赋一个初始化值、let - 声明一个块作用域的局部变量,可赋一个初始化值、const - 声明一个块作用域的只读的命名常量。 1.2 重复声明和遗漏声明 使用 var 命令重复声明变量是合法的,就跟重新赋值一样。 如果你试图读取一个没有声明的变量,JavaScript 会报错。然而,...
javaScript编译原理及作用域
    javascript是一门编译型语言。    传统编译语言流程分为:分词/词法分析;解析语法分析;代码生成。        分词/词法分析:将字符串代码分解为有意义的代码块。这些代码块被称为词法单元。        解析/语法分析:将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树(抽象语法树)。        代码生成:将抽象语法树转换为可执行的代码的过程称为代码...
JS中的块级作用域,var、let、const三者的区别
首先,ECMAScript和JavaScript关系:       ECMAScript是一个国际通过的标准化脚本语言。JavaScript由ECMAScript和DOM、BOM三者组成。可以简单理解为:ECMAScript是JavaScript的语言规范,JavaScript是ECMAScript的实现和扩展。1. 块作用域{ }JS中作用域有:全局作用域、函数作用域。没有块作用域的概念。ECM
深入理解javascript作用域系列第五篇——一张图理解执行环境和作用域
前面的话 对于执行环境(execution contexr)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关于作用域的两种不同翻译而已。但实际上,它们并不相同,却相互纠缠在一起。 概念 【作用域】:作用域是一套规则,用于确定在何处以及如何查找标识符。关于LHS查询和RHS查询详见作用域系列第一篇内部原理。 作用域分为词法作用域和动态作用域。javascr...
理解JavaScript的变量,变量作用域,作用域链
JavaScript的变量,变量作用域,作用域链
js 原型链 及 作用域链 及 this指向问题 白话理解
js 作用域链: 推荐一篇文章https://www.cnblogs.com/wangfupeng1988/p/3986420.html 一段拗口的话,理解一下:当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问 作用域:一个变量的作用域(scope)是程序源代码中定义的这个变量的区域。(注意变量的作用域是定义这个变量时决定...
关于JavaScript作用域的习题和解析
题一:function Foo(){ var i=0; return function(){ document.write(i++); }}var f1=Foo();f2=Foo();f1();f1();f2();//输出的结果是 0 1 0解析:这是一个闭包,闭包的作用有两个,一是可以读取函数内部的变量,二是让这些变量的值始终保存在内存中。当f1()和f2()调用时,会创建两个执行环境,保存各...
JavaScript静态作用域和动态作用域
动态作用域; 静态作用域
文章热词 机器学习教程 Objective-C培训 交互设计视频教程 颜色模型 设计制作学习
相关热词 mysql关联查询两次本表 native底部 react extjs glyph 图标 java传参学习 区块链问题