转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/25076713
一直觉得Js很强大,由于长期不写js代码,最近刚好温故温故。
1、Javascript没有代码块作用域的概念,局部作用域是针对函数来说的。
function fun()
{
for( var i = 0 ; i < 10 ; i++)
{}
//如果在Java中i此时应当属于未声明的变量,但是Js中i的作用域依然存在
console.log(i);//10
if(true)
{
var b = "helloworld";
}
console.log(b);//helloworld
}
fun();
2、如果不使用var声明的变量,默认为全局变量
function fun02()
{
a = "helloworld";
var b = "welcome";
}
fun02();
console.log(a); // helloworld
console.log(b); // b is not defined
3、Js中的作用域链
先看个简单的例子:只有一个函数对象,函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
var a = "hello";
function fun04()
{
a = "world";
var b ="welcome";
}
作用域链的图:
注:图中省略了,Global Scope中的window,document等,每个函数对象中的arguments,this等均未画出。
function fun03()
{
var a = 10;
return function(){
a*= 2 ;
return a ;
};
}
var f = fun03();
f();
var x = f();
console.log(x); //40
var g = fun03();
var y = g();
console.log(y); //20
观察上面代码,存在fun03,f,g三个函数对象。
下面是作用域链的图:
注:每个函数对象一个作用域链,这里直接画在了一起;对于变量的查找,先从链的0开始找。
函数对象 f 在代码中执行了2 次,所以a*2*2 = 40 ; 函数对象 g 在代码中执行了1次, 所以 a *2 = 20 ;
4、闭包
上面的例子可以看到,在fun03执行完成后,a的实例并没有被销毁,这就是闭包。个人对闭包的理解是:函数执行完成后,函数中的变量没有被销毁,被它返回的子函数所引用。
下面以一个特别经典的例子,同时使用作用域链解析:
window.onload = function()
{
var elements = document.getElementsByTagName("li");
for(var i = 0; i < elements.length ; i ++)
{
elements[i].onclick = function()
{
alert(i);
}
}
}
相信上面的代码肯定大家都写过,本意是点击每个li,打印出它们的索引,可是事实上打印出的都是elements.length。这是为什么呢?
看下上面的简易的作用域链(省略了很多部分,主要是理解),此时每个onclick函数的i,指向的都是 onload 中的i 此时的 i = element.length.
下面看解决方案:
window.onload = function ()
{
var elements = document.getElementsByTagName("li");
for (var i = 0; i < elements.length; i++)
{
(function (n)
{
elements[n].onclick = function ()
{
alert(n);
}
})(i);
}
}
在onclick函数的外层,包了一层立即执行的函数,所以此时的n指向的 n 是立即执行的,所有都是1~elements.length 。
分享到:
相关推荐
本文实例讲述了JavaScript词法作用域与作用域链。分享给大家供大家参考,具体如下: 一、作用域 域表示的就是范围,即作用域,就是一个名字在什么地方可以使用,什么时候不能使用。想了解更多关于作用域的问题推荐...
Web-前端教程37 JS进阶:作用域.zip
当代码在一个环境中执行,会创建变量对象的一个作用域链。 用途:保证对执行环境有权访问的所有变量和函数有序访问。 特点:作用域链的前端始终是当前执行的代码所在的环境的变量对象。如果这个环境是函数,则将其...
为了更好的理解,在阅读此文之前建议先阅读上一篇《JavaScript词法作用域与作用域链》 1.什么是闭包 闭包的含义就是闭合,包起来,简单的来说,就是一个具有封闭功能与包裹功能的结构。所谓的闭包就是一个具有封闭...
文章目录1 严格模式1.1 什么是严格模式1.2 开启严格模式3.3 严格模式中的变化2 高阶函数3 闭包3.1 变量作用域3.2 什么是闭包3.3 闭包案例3.4 闭包总结4 递归4.1 什么是递归4.2 利用递归求数学题4.3 利用递归求:根据...
'千锋python基础教程:7、装饰器&偏函数与作用域与异常处理与文件读写' 千锋python基础教程:8、os与窗口控制与内存修改与语言 第二章前端基础 1、html&css;基础 2、html&css;提升 3、JavaScript基础 4、...
2.2作用域 2.3简单类型 2.4常量:有名称但不改变 2.5习题 第3章运算符和语句 3.1JavaScript语句的格式 3.2简单语句 3.3条件语句和程序流 3.4条件运算符 3.5逻辑运算符 3.6高级语句:循环语句 3.7习题 第4章...
1 利用js作用域链 作用域链(scope chain) 当执行一段JavaScript代码(全局代码或函数)时,JavaScript引擎会创建为其创建一个作用域又称为执行上下文(Execution Context),在页面加载后会首先创建一个全
1、JavaScript中定义函数有2钟方法: 1-1.函数声明: 代码如下:function funcName(arg1,arg2,arg3){ //函数体} ①name属性:可读取函数名。非标准,浏览器支持:FF、Chrome、safari、Opera。 ②函数声明提升:指...
包括了css,javascript,vue,webpack,vite,html5新特性等等,包括了面试中比较常见的BFC,v8垃圾回收机制,vite和webpack的区别,vue中遇到的问到,防抖节流,深拷贝,浅拷贝,盒子模型,作用域,闭包,浏览器...
前言在JavaScript中,作用域、上下文、闭包、函数等算是精华中的精华了。对于初级JSer来说,是进阶必备。对于前端攻城师来说,只有静下心来,理解了这些精华,才能写出优雅的代码。 本文旨在总结容易忘记的重要知识...
JavaScript基础:变量、常量、数据类型、类型转换、运算符、语句、数组、函数、对象、堆栈 ...JavaScript高级:作用域、函数进阶、解构赋值、构造函数、编程思想、原型、深浅拷贝、异常处理、this、防抖节流
前端进阶JavaScript基础:JavaScript数据类型JavaScript代码运行机制作用域和作用域链let/const/var的区别JavaScript高阶编程技巧原型和原型链的底层运行机制this指向数据类型检测JavaScript类的继承方案JavaScript...
JavaScript: 数据类型、面向对象、继承、闭包、插件、作用域、跨域、原型链、模块化、自定义事件、内存泄漏、事件机制、异步装载回调、模板引擎、Nodejs、JSON、ajax等。 其他: HTTP、安全、正则、优化、重构、...
作用域链和闭包 this解析 原型和原型链 继承 JS进阶 call和apply模拟实现 bind模拟实现 new模拟实现 深浅拷贝 函数柯里化 防抖和节流 函数递归 ES6 let, const Symbol, Iterator和Map Generator, Promise和Async ...
包括了css,javascript,vue,webpack,vite,html5新特性等等,包括了面试中比较常见的BFC,v8垃圾回收机制,vite和webpack的区别,vue中遇到的问到,防抖节流,深拷贝,浅拷贝,盒子模型,作用域,闭包,浏览器...
内容以《JavaScript高级程序设计》为基础,包括基本语法、数据类型、变量和作用域、面向对象、函数表达式、DOM、BOM、事件等 03-JavaScript进阶 内容以《JavaScript高级程序设计》、《ES6入门教程》和各个前端框架...
作用域、作用域链015.Reflect016.Proxy017.void018.函数柯里化019.bind、apply、call020.cookie、session、token进阶node001....