问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

JS块级作用域和私有变量实例分析

发布网友 发布时间:2022-04-24 09:33

我来回答

2个回答

懂视网 时间:2022-04-07 13:49

每声明一个函数就会产生一个作用域。而外面的作用域访问不了里面的作用域(把里面的变量和函数隐藏起来),而里面的可以访问到外面的。对于隐藏变量和函数是一个非常有用的技术。

基于作用域隐藏的方法叫做最小授权或最小暴露原则。

这个原则是指在软件设计中,应该最小限度的暴露必要内容,而将其内容都隐藏起来,比如某个模块或对象得API设计。隐藏变量和函数可以解决同名标识符的之间的冲突,冲突会导致变量的意外覆盖。

例如:

var a = 2;
function foo(){
 var a = 3;
 console.log(a);
}
foo();
console.log(a);

虽然这种技术可以解决一些问题,但是他并不理想,会导致一些额外的问题,首先必须声明一个具名函数foo(),意味着foo这个名称本身“污染”了所在的作用域,其次必须显式的通过函数名foo()调用这个函数才能运行其中的代码。

如果函数不需要函数名,并且能够自动运行,这会更加理想。幸好js提供了同时解决这两个问题的方案 -- (IIFE) Immediately Invoked Function Expression -- 立即执行函数

var a = 2;
(function foo(){
 var a = 3;
 console.log(a);
})()
console.log(a);

首先立即执行函数不会当做函数声明处理而是当做函数表达式处理。

区分函数声明还是函数表达式:看function在声明中是不是第一个词,如果是第一个词就是函数声明否则就是函数表达式。而立即执行函数" (function ",不是" function ",所以是函数表达式。

函数声明和函数表达式之间最重要的区别是他们的名称标识符将会绑定在何处

函数声明的函名称数会绑定在当前作用域内。假如在全局作用域创建一个函数声明,就可以在全局作用域访问这个函数名称并执行。而函数表达式的函数名称会绑定在自身的函数中,而不是当前说在作用域中。例如你全局创建一个函数表达式,如果你直接执行这个你创建的函数表达式的函数名就会报错,因为当前作用域下没有这个标识符,而你在函数表达式里面的作用域里访问这个函数名就会返回这个函数的引用。

作用域闭包,嗯,闭包这儿两个字就有点让人难以理解,(可以想象成一个包是关上的,里面隐藏了一些神秘的东西)而对于闭包的定义是这样说的:当函数可以记住并访问所在的作用域时,就产生了闭包,即使函数是在当前作用域之外执行。

for instance(拽个英文,哈哈)。

function foo() {
 var a = 2;
 function bar() {
 console.log(a);
 }
 bar();
}
foo();

上面的 代码bar()可以访问外部作用域中的变量。根据上面的定义这是闭包吗?从技术来讲也许是,但我们理解的是作用域在当前作用域查找变量如果没找到会继续向上面查找,找到返回,找不到继续找,直到全局作用域。-- 而这些正是闭包的一部分。函数bar()具有一个涵盖foo()作用域的闭包。

function foo(){ var a = 2; function bar (){
 console.log(a);
 } return bar;
}var baz = foo();
baz();

在上面的代码更好的展示了闭包。

bar()函数在定义时作用域以外的地方执行(此时在全局作用域执行)。在foo()函数执行后,通常会期待foo()整个内部作用域都被销毁,因为我们知道引擎有垃圾回收器用来释放不在使用的内存空间,由于foo()已经执行完,看上去内容不会再被使用,所以很自然的会考虑对齐进行回收,回收后意味着里面的函数和变量访问不到了。foo()执行完,baz变量存着bar函数的引用。当执行baz也就是bar函数时。console.log(a)。不理解闭包的人可能认为会报错,事实上,打印的是2;???what?

foo()函数作用域不是执行完销毁了吗?怎么还能访问到a变量?-- 这就是闭包。

当foo()执行后,bar函数被返回全局作用域下,但是bar函数还保留着当时的词法作用域(当时写代码是的顺序就已经定义了作用域,这个作用域叫词法作用域--外面函数套着里面的函数的那种)甚至直到全局作用域。所以bar还留有foo()函数的引用。使得foo()函数没有被回收。

闭包可以说不出不在,只是你没有发现认出他。在定时器,事件监听器,ajax请求,跨窗口通信或者任何其他的异步(或者同步)任务中,只要使用了回调函数,实际上就是使用闭包。

for instance

function wait(message) {
 setTimeout(function timer() {
 console.log(message);
 }, 1000);
}
wait("hello");

在上面的代码中将一个内部函数(名为timer)传递给setTimerout(...).timer具有涵盖wait(...)的作用域的闭包。因此还保有对变量message的引用。wait()执行1000毫秒后,它的内部作用域不会消失,timer函数依然保有wait()作用域的闭包。

而闭包和立即执行函数息息相关。

循环和闭包

for(var i = 1; i <= 5; i++){
 setTimeout(function timer(){
 console.log(i);
 },i*1000);
}

上面代码我们以为输出的会是1-5,可事实上输出的是5个6,这是为啥啊 -- 闭包啊。

延迟函数的回调会在循环结束时执行。事实上,当定时器运行时即使每个迭代的是setTimerout(...,0),所有的回调函数依然是循环结束后才会执行。我猜是跟js执行机制有关系吧。至于为什么都是6. 因为即使5个函数是在各个迭代中分别定义的,但是他们又被封闭在一个共享的全局作用域中因此实际上只有一个i.而怎么解决呢,立即执行函数来了!!!

for (var i = 1; i <= 5; i++) {
 (function (i) {
 setTimeout(function timer() {
  console.log(i);
 }, i * 1000);
 })(i)

}

打印出来1,2,3,4,5了欧,这回是你想要的数了。解释一下,5次循环创建了5个立即执行函数,这5个函数的作用域都不相同,立即函数接收的参数是当前循环的i.所以当timer执行时访问的就是自己立即执行函数对应的作用域。也就是说5个timer函数分别对应5个作用域,每个作用域保存的变量i都不同,解决啦!!!

你懂闭包了吗?

js执行机制

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。JavaScript语言的设计者意识到这个问题,将所有任务分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。

哪些语句会放入异步任务队列及放入时机一般来说,有以下四种会放入异步任务队列:setTimeout 和 setlnterval ,DOM事件,ES6中的Promise,Ajax异步请求

本文来自 js教程 栏目,欢迎学习!

热心网友 时间:2022-04-07 10:57

本文实例讲述了JS块级作用域和私有变量。分享给大家供大家参考,具体如下:
块级作用域
(function(){
//这里是块级作用域
})()
例如:
(function(){
for(var
i=0;i<5;i++){
alert(i);//0,1,2,3,4
}
})();
alert(i);//error
上例中,定义了一个块级作用域,变量i在块级作用域中可见的,但是在块级作用域外部则无法访问。
这种技术经常在全局作用域中被用在函数外部,从而*向全局作用域中添加过多的变量和函数。
私有变量
任何在函数中定义的变量,都可以认为是私有变量。因为不能在函数的外部访问这些变量。私有变量包括函数的参数、局部变量和在函数内部定义的其他函数。
我们把有权访问私有变量和私有函数的公有方法称为特权方法:
function
MyObject(){
//私有变量和私有函数
var
privateVariable
=
10;
function
privateFunction(){
return
false;
}
//特权方法,特权方法作为闭包有权访问在构造函数中定义的所有变量和函数
this.publicMethod
=
function
(){
privateVariable++;
return
privateFunction();
};
}
var
obj
=
new
MyObject();
obj.publicMethod();//
原型模式定义共有方法:
(function(){
//私有变量和私有函数
var
privateVariable
=
10;
function
privateFunction(){
return
false;
}
//构造函数
MyObject
=
function(){
};
//公有/特权方法
MyObject.prototype.publicMethod
=
function(){
privateVariable++;
return
privateFunction();
};
})();
模块模式:
var
singleton
=
function(){
//私有变量和私有函数
var
privateVariable
=
10;
function
privateFunction(){
return
false;
}
//特权/公有方法和属性
return
{
publicProperty:
true,
publicMethod
:
function(){
privateVariable++;
return
privateFunction();
}
};
}();
更多关于JavaScript相关内容可查看本站专题:《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数*算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
您可能感兴趣的文章:详解JavaScript
新语法之Class
的私有属性与私有方法JavaScript私有变量实例详解浅谈js继承的实现及公有、私有、静态方法的书写深入了解JavaScript
私有化
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
为什么来大姨妈胸会胀 少儿学什么舞蹈 青年学什么舞蹈好 成年人学什么舞蹈 福州企业最低工资标准 2013年厦门的底薪是多少 生产要素的需求有哪些性质 生产要素的需求有何特点? 什么是生产要素需求 微观经济学要素需求什么是条件要素需求?它和要素需求有什么不同?_百度... 想和男朋友分手该怎么说才委婉? javascript中调用函数和变量都需要创建对象吗,需要为什么,不需要又为 ... 想跟男朋友分手该怎么说 写出你所知道的javascript系统函数及常用对象,并且说明用途 js函数作用域和对象作用域里变量的不同 00 bang’s blog javascript中函数创建对象并执行的问题 javascript函数、事件、对象、方法的通俗解释和他们的作用。 javascript的创建和删除对象的实训报告怎么写 如何理解 JavaScript 中作为参数的函数的作用域和 this 莲蓉月饼的做法步骤图,莲蓉月饼怎么做好吃 莲蓉馅蛋黄酥的家常做法大全怎么做好吃视 请问白莲蓉月饼怎么做才好吃? 莲蓉月饼怎样做好吃呢? 广式莲蓉月饼的做法,广式莲蓉月饼怎么做好吃 木糖醇莲蓉馅的做法,木糖醇莲蓉馅怎么做好吃 哪个牌子的白莲蓉馅料儿好吃? 月饼真的很好吃吗? 怎么做莲蓉馅/红糖发糕才好吃美味 美心双黄白莲蓉 双黄莲蓉 哪个好吃 豆沙和莲蓉到底有什么区别?? 我想跟男朋友分手了!但是不知道怎么说,该怎么办? 关于javaScript中的全局变量和成员变量以及this在函数中的作用域问题... 关于javascript 中(function(){})()的作用和用法 苹果相机怎么设置九宫格 javascript用带参数的构造函数定义一个对象Cat 我的苹果手机相机怎么没有九宫格 新手求解js的对象,属性,方法,的关系。内有具体例子 在javascript中,Function对象的本质是什么? 苹果手机怎么设置九宫格相机 javascript function 参数 为什么我的苹果xs max的相机设置没有九宫格? 请问减肥可以吃香干豆腐吗? 豆干减肥期间可以吃吗 滴滴车主分低的连单,分高的没活是什么情况 豆干减肥可以吃吗 听说燃油车跑滴滴,成本真的伤不起,是真的吗? 求《望江南》整首诗的诗意啊! 谢谢啦!! 滴滴实习期80分,一单没有 欧阳修写的望江南诗意是什么。 滴滴服务分80以上更难接单吗?