词法作用域
上回书说到,我们将作用域定义为一套规则,这套规则用来管理引擎如何查找变量,而作用域的工作模型主要有两种: 词法作用域
和动态作用域
,词法作用域
是最普遍的,被大多数编程语言使用,JS也是使用的这种模型.作用域如何工作就是由其采用的工作模型确定的
词法阶段
在第一章中说过,源代码执行前会经历三个阶段: 分词/词法分析
,解析/语法分析
,生成机器指令
.第一个阶段就是词法阶段.
静态作用域
词法作用域就是定义在词法阶段的作用域,也可以说: 词法作用域
是由写代码时变量写在哪里决定的,因此作用域在写代码时就确定了.(大部分情况是这样,当使用eval,with
时,词法作用域是可以动态修改的)
在没有深入js之前就听过一句话: ''js的作用域是静态的'',现在知道了这句话的依据,那就是js的作用域使用的工作模型是词法作用域
,词法作用域
在词法阶段
就已经确定了,
遮蔽效应
作用域查找会在找到第一个匹配的标识符时停止,因此内层作用域和外层作用域的同名变量,由内向外查找时优先使用内层的变量
欺骗词法
上文中说,作用域可以通过eval
和with
动态修改,来欺骗词法作用域,然而这种做法是非常不推荐的: 欺骗词法作用域只会导致性能下降
eval
js中eval()
可以接收一个字符串作为参数,并将其中内容视为好像书写时就存在该位置的代码进行运行.
因此根据传递的字符串,可以动态的修改当前作用域:
scss复制代码function foo(str, a) {
eval(str);
console.log(a, b);
}
var b = 2;
foo('var b = 3', 2); //输出2 3而非2 2
如果作用域没有改变,当执行console.log(a,b)
时,会对b进行RHS,发现当前作用域没有,便向外部作用域查找,并返回2
然而由于由eval的存在,将var b = 3
当作本来就在这个位置进行处理,结果就变成: 当执行console.log(a,b)
时,对b进行RHS,由于使用eval
在当前作用域动态声明了一个b
变量,那么由于遮蔽效应,直接使用当前作用域的变量b
另: 严格模式下,eval()有自己的词法作用域,此时无法修改所在作用域的
与eval
类似setTimeout,setInterval
的第一个参数可以是字符串,也会被当作动态生成的代码函数,new Function
的最后一个参数也可以接收字符串并将其转换成动态函数
with
with()
接收一个参数作为作用域:
ini复制代码var obj = {
a:1,
b:2,
c:3
}
修改obj的属性时:
obj.a = 2;
obj.b = 3;
obj.c = 4;
使用with()后:
with(obj){
a = 2;
b = 3;
c = 4;
}
with单独形成一个obj的作用域,在这个作用域下访问变量都是obj上的属性
与eval
修改作用域不同,with
是创建一个全新的词法作用域,我们传递obj
给whit
时,with
所声明的作用域就是obj
再看一个泄漏的例子:
scss复制代码function foo(obj){
with(obj){
a=2
}
}
var o1 = {
a:1
}
var o2 = {
b:2
}
foo(o1)
console.log(o1.a) //2
foo(o2)
console.log(o1.b) //undefined
console.log(a) // 2,a直接泄漏到全局作用域中
上述例子中,执行foo(o1)
时,由于o1
中包有a属性,所以一切正常,将o1.a赋值为2,当执行foo(o2)
时,由于o2
没有a属性,所以没有赋值o2.a为undefined,那么为什么在全局作用域打印a也能成功呢?
其实foo(o2)
的整个过程是这样的: 由于whit
创建了一个新的作用域,那么整个作用域嵌套式这样的: o2作用域 => 函数作用域 => 全局作用域,当执行a=2
时,对a
进行RHS,发现o2作用域没有该变量,于是就去函数作用域查找,直到全局作用域都没有,于是在全局作用域隐式声明了a
性能问题
为什么说eval
和with
会对性能有很大的影响呢?其实真正对性能产生影响的是不确定的作用域的产生
在JavaScript中引擎会在编译阶段做很多性能优化,其中有些优化依赖于能够根据代码的词法
做静态分析
,并且预先确定所有变量和函数定义的位置,以便需要的时候能快速找到.
但是如果代码中使用了eval
和with
,就不能在词法阶段确定作用域是否进行了修改,如何修改,进而预先确定所有变量和函数的定义位置的优化就无法进行,进行了也是无意义的,最坏的情况就是不做任何优化.因此如果代码大量使用了eval,with
,那么运行起来一定会很慢.
在数字化时代,IP地址作为互联网用户的“数字指纹”,扮演着至关重要的角色。它不仅是设备接入网络的唯一标识,还常常与用户的地理位置紧密相连。然而,随着移动互联网的普及和人们日常活动的多样化,一个有趣的现象逐渐显现:IP地址似乎也在随着用户的移动而“迁徙”。那么,ip地址会因为位置不同而改变吗?这种变化又如何影响我们的在线身份与体验?下面跟着虎观代理小二一起来了解一下吧。
一、IP地址的基础知识
首先,让我们简要回顾一下IP地址的基本概念。IP地址,即互联网协议地址,是分配给连接到互联网的每台设备的唯一数字标识。它分为IPv4和IPv6两种版本,其中IPv4是目前广泛使用的版本,由四个0到255之间的数字组成,用点分隔(如192.168.1.1)。而IPv6则是为了解决IPv4地址枯竭问题而设计的,提供了更长的地址空间。
二、IP地址与地理位置的关系
通常情况下,IP地址与地理位置之间存在一定的对应关系。这种关系主要依赖于互联网服务提供商(ISP)的网络架构和地理分布。ISP会根据用户的物理位置分配相应的IP地址段,使得通过IP地址可以大致判断用户的地理位置。然而,这种对应关系并非绝对固定,因为存在多种因素可能导致IP地址与地理位置的不一致。
三、影响IP地址的因素
-
移动设备的普及:随着智能手机、平板电脑等移动设备的普及,用户越来越频繁地在不同地点接入互联网。这些设备通常会自动连接到最近的无线网络或移动基站,从而改变其IP地址。
-
代理服务:用户为了隐私保护或访问特定地区的内容,可能会使用代理服务。这些服务会为用户分配一个新的IP地址,该地址可能与用户的实际地理位置无关。
-
ISP的网络调整:ISP有时会进行网络架构的调整或升级,这可能导致用户IP地址的变动。此外,ISP还可能为了负载均衡或故障恢复而动态调整用户的IP地址
文章结尾
综上所述,IP地址确实会因为位置的不同而发生改变,这种变化是多种因素共同作用的结果。在享受互联网带来的便利与自由的同时,我们也应关注IP地址变化对在线身份和隐私安全的影响。通过合理使用代理服务等工具,我们可以更好地保护自己的隐私和安全;同时,也应对互联网服务提供商的网络调整保持关注,以便及时调整自己的网络设置和访问策略。
热门推荐
评论记录:
回复评论: