javascript 作用域、作用域链理解

时间:2025年03月21日

/

来源:shouji88

/

编辑:本站小编

收藏本文

下载本文

下面是小编帮大家整理的javascript 作用域、作用域链理解,本文共6篇,希望对大家的学习与工作有所帮助。本文原稿由网友“shouji88”提供。

篇1:javascript 作用域、作用域链理解

JavaScript作用域就是变量和函数的可访问范围,

1.变量作用域

在JavaScript中,变量作用域分为全局作用域和局部作用域。

全局作用域

任何地方都可以定义拥有全局作用域的变量

1.没有用var声明的变量(除去函数的参数)都具有全局作用域,成为全局变量,所以声明局部变量必须要用var

2.window的所有属性都具有全局作用域

3.最外层函数体外声明的变量也具有全局作用域

var globalScope=“globalScope”;

function checkScope{

var partScope=“part”;

scope=“scope”;

}

checkScope();

console.log(globalScope);//globalScope,全局变量

console.log(scope);    //scope,全局变量

console.log(partScope);//Uncaught ReferenceError: partScope is not defined,报错:没有定义partScope

局部作用域

1.函数体内用var声明的变量具有局部作用域,成为局部变量

2.函数的参数也具有局部作用域

var globalScope=“globalScope”;

function checkScope(x){

scope=“scope”; //变成了全局变量

var partScope=“part”;//在函数体内,声明局部变量一定要加var

var globalScope=“partScope”;

}

checkScope(12);

console.log(globalScope);//globalScope,在函数体内,局部变量的优先级高于全局变量

console.log(scope);//scope,全局变量 console.log(partScope);

console.log(partScope);// Uncaught ReferenceError: partScope is not defined,局部变量外面访问不到

console.log(x);//局部变量外面访问不到

总结:在函数体内局部变量的优先级高于同名的全局变量,声明局部变量必须用var

2.函数作用域

一些类C语言是块级作用域(block scope),每一个花括号是一个作用域,花括号内的代码对外是不可见的,

JavaScript是函数作用域(function scope),没有块级作用域。无论函数体内的变量在什么地方声明,对整个函数都是可见的,即JavaScript函数里声明的所有变量都被提前到函数体的顶部,只是提前变量声明,变量的赋值还是保留在原位置

函数作用域只能用函数来声明独立作用域,并不是每一个花括号都是一个独立作用域,例如:for循环并不能创建一个局部的作用域

for(var i=0;i<5;i++){

var scope='scope';

}

console.log(i) //5;i仍然存在,因为JavaScript是函数作用域而不是块级作用域

console.log(scope);//scope;scope仍然存在

function checkScope(){

console.log(funScope); // undefined,函数里声明的所有变量都被提前到函数体的顶部,所以funScope才会认为已经存在

var funScope=“funScope”;

}

checkScope();

3.作用域链

作用域链:JavaScript的变量都是对象的属性,而该对象可能又是其它对象的属性,而所有的对象都是全局对象的属性,所以这些对象的关系可以看作是一条链,

链头就是变量所处的对象,链尾就是全局对象

function checkScope(scope){

var funScope=“funScope”;

var s=scope;

}

在查找变量funScope的值时,会先查找当前对象,如果当前对象查不到就继续查找作用域链上面的下一个对象,如果作用域链上没有一个对象包含此属性,就抛出引用错误。

在不包含嵌套的函数体内,作用域链上有两个对象:

1.定义函数参数和局部变量的对象

2.全局对象

在包含嵌套的函数体内,作用域链上至少有三个对象

篇2:故障解析:DHCP作用域

下面我们主要讲解一下通过DHCP作用域来处理故障的问题,笔者所在学校有两个机房,机房A的计算机是指定IP地址,机房B的计算机采用DHCP服务自动获取IP地址。两个机房在同时使用并上网时,部分计算机经常出现故障(如上不了网、速度缓慢)。

原因分析

每次指定IP地址的机房A先开机时,该机房内的所有计算机都能正常上网;若采用自动获取(DHCP)IP地址的机房B先开机时,则会引发机房B与机房A内的计算机IP地址冲突,致使部分>计算机不能上网。于是,笔者决定在机房B的DHCP作用域中留出指定IP地址段,以避免IP地址冲突。

解决过程

在重新设置好DHCP作用域后,笔者并没有重新启动Windows Server(服务器系统),结果出现机房B里的所有计算机不能上网的新问题。开始以为是接入线路有故障,但用测试仪器检测正常;遂怀疑集线器硬件有问题,认为是由于硬件损坏引起的广播风暴导致的,更换集线器后故障依旧;再考虑是否有多余的线路构成了回路,使数据包不断发送和校验数据,从而导致不能上网,笔者马上去掉所有连接确保不会构成回路,只针对机房B配备一个集线器,问题还是存在;当笔者已经感到山穷水尽时,无意中重新启动服务器,问题立即得到解决,

总结

当指定IP地址和由DHCP获取IP地址发生冲突而导致部分计算机不能上网时,应当在DHCP作用域中预留出指定的IP地址段,避免IP地址重复;而在重新设置好DHCP作用域后,出现用DHCP自动获取IP地址的机房里的所有计算机不能上网,是由于Windows 2000 Server没有重新启动导致的,可看出在Windows 2000 Server中进行网络设置后不用重新启动即可生效是不可靠的;另外,使用逐步排除法也是解决类似问题的一个好方法。

篇3:Spring bean的作用域

下面通过一个例子来演示怎么自定义作用域并且分析框架中的代码自定义作用域是怎么实现,这个自定义scope的功能是把bean缓存到一个LRU缓存中,当bean被踢出缓存时触发析构回调

实现Scope接口,LRU缓存中最多只能放两个bean,被踢掉的bean会触犯析构回调,在removeEldestEntry方法中,析构回调保存在destructionCallback哈希表中:

public class LRUCacheScope implements Scope { private class BeanCache extends LinkedHashMap{ private static final long serialVersionUID = -887300667768355251L; @Override protected boolean removeEldestEntry(Entryeldest) { boolean flag = size >maxBeanNumber; if (flag) { executeDesCallback(eldest.getKey()); } return flag; } } private static final int DEFAULT_MAX_BEAN_NUMBER = 2; private MapbeanCache = Collections .synchronizedMap(new BeanCache()); private int maxBeanNumber; private MapdestructionCallback = new HashMap(); public LRUCacheScope() { this(DEFAULT_MAX_BEAN_NUMBER); } public LRUCacheScope(int maxBeanNumber) { super(); this.maxBeanNumber = maxBeanNumber; } @Override public Object get(String name, ObjectFactory<?>objectFactory) { Object bean = beanCache.get(name); if (bean == null) { bean = objectFactory.getObject(); beanCache.put(name, bean); } return bean; } @Override public Object remove(String name) { destructionCallback.remove(name); return beanCache.remove(name); } @Override public void registerDestructionCallback(String name, Runnable callback) { destructionCallback.put(name, callback); } @Override public Object resolveContextualObject(String key) { return null; } @Override public String getConversationId() { return null; } private void executeDesCallback(String beanName) { Runnable callBack = destructionCallback.get(beanName); if (callBack != null) { callBack.run(); } destructionCallback.remove(beanName); }}定义CustomScopeConfigurer注册Scope,并且定义其它的测试bean

JUnit测试代码

@Testpublic void test() { BeanFactory context = new ClassPathXmlApplicationContext( “spring/beans/scope/scope.xml”); ScopedBean bean1 = (ScopedBean) context.getBean(“scopedBean1”); ScopedBean bean11 = (ScopedBean) context.getBean(“scopedBean1”); assertEquals(bean1, bean11); ScopedBean bean2 = (ScopedBean) context.getBean(“scopedBean2”); ScopedBean bean3 = (ScopedBean) context.getBean(“scopedBean3”); bean11 = (ScopedBean) context.getBean(“scopedBean1”); assertNotEquals(bean1, bean11);}

执行测试代码发现代码执行通过,可以发现最后一次取出的scopedBean1和前面的scopedBean1已经不是一个实例了,查看控制台日志发现有如下信息:

22:28:48,738 DEBUG DefaultListableBeanFactory:432 - Creating instance of bean 'scopedBean1'22:28:48,738 DEBUG DefaultListableBeanFactory:460 - Finished creating instance of bean 'scopedBean1'22:28:48,738 DEBUG DefaultListableBeanFactory:432 - Creating instance of bean 'scopedBean2'22:28:48,738 DEBUG DefaultListableBeanFactory:460 - Finished creating instance of bean 'scopedBean2'22:28:48,738 DEBUG DefaultListableBeanFactory:432 - Creating instance of bean 'scopedBean3'22:28:48,738 DEBUG DefaultListableBeanFactory:460 - Finished creating instance of bean 'scopedBean3'22:28:48,738 DEBUG DisposableBeanAdapter:227 - Invoking destroy() on bean with name 'scopedBean1'destroy:spring.beans.scope.ScopedBean@18235ed22:28:48,738 DEBUG DefaultListableBeanFactory:432 - Creating instance of bean 'scopedBean1'22:28:48,738 DEBUG DefaultListableBeanFactory:460 - Finished creating instance of bean 'scopedBean1'22:28:48,738 DEBUG DisposableBeanAdapter:227 - Invoking destroy() on bean with name 'scopedBean2'destroy:spring.beans.scope.ScopedBean@1a28362从日志可以看出在创建完scopedBean3并且添加到缓存中之后scopedBean1被踢掉了并且触发了析构回调,我们ScopedBean实现了DisposableBean接口,它的destroy方法被调用了:

public class ScopedBean implements DisposableBean { @Override public void destroy() throws Exception { System.out.println(“destroy:” + this); }}

篇4:Spring bean的作用域

现在大致分析一下自定义作用域时如何实现的

首先看下CustomScopeConfigurer类,看下它的postProcessBeanFactory方法:

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (this.scopes != null) { for (Map.Entryentry : this.scopes.entrySet()) { String scopeKey = entry.getKey(); Object value = entry.getValue(); if (value instanceof Scope) { beanFactory.registerScope(scopeKey, (Scope) value); } else if (value instanceof Class) { Class scopeClass = (Class) value; Assert.isAssignable(Scope.class, scopeClass); beanFactory.registerScope(scopeKey, (Scope) BeanUtils.instantiateClass(scopeClass)); } else if (value instanceof String) { Class scopeClass = ClassUtils.resolveClassName((String) value, this.beanClassLoader); Assert.isAssignable(Scope.class, scopeClass); beanFactory.registerScope(scopeKey, (Scope) BeanUtils.instantiateClass(scopeClass)); } else { throw new IllegalArgumentException(“Mapped value [” + value + “] for scope key [” +scopeKey + “] is not an instance of required type [” + Scope.class.getName() +“] or a corresponding Class or String value indicating a Scope implementation”); } } }}在这个方法中把所有scope都注册到beanFactory中,来看看bean工厂的registerScope方法,在AbstractBeanFactory类中,在这个方法中把所有的作用域对象都存储到了scopes哈希表属性中,作用域名称作为哈希表的key:

public void registerScope(String scopeName, Scope scope) { Assert.notNull(scopeName, “Scope identifier must not be null”); Assert.notNull(scope, “Scope must not be null”); if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) { throw new IllegalArgumentException(“Cannot replace existing scopes 'singleton' and 'prototype'”); } this.scopes.put(scopeName, scope);}接下来看看bean的获取方法,在AbstractBeanFactory的doGetBean方法中,看doGetBean方法的代码片段:

if (mbd.isSingleton()) { ... }else if (mbd.isPrototype()) { ... }else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException(“No Scope registered for scope '” + scopeName + “'”); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory() { public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, “Scope '” + scopeName + “' is not active for the current thread; ” + “consider defining a scoped proxy for this bean if you intend to refer to it from a singleton”, ex); }}可以看到获取自定义scope的bean调用了Scope的get方法,如果作用域没有缓存要找bean,那么会调用createBean来创建一个实例,这块创建bean实例的逻辑和prototype bean的是一样的,

下面来看看注册析构回调的代码,在AbstractBeanFactory类的registerDisposableBeanIfNecessary方法中,在bean创建(AbstractAutowireCapableBeanFactory的doCreateBean方法)完成之后:

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException(“No Scope registered for scope '” + mbd.getScope() + “'”); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } }}代码中可以看到自定义scope的bean创建完成之后会注册一个DisposableBeanAdapter析构回调到到Scope,看看DisposableBeanAdapter这个类的代码,在scope中执行回调时调用run方法,而run方法会直接调用destroy方法,主要代码在destroy方法中,从代码中可以看出在destroy方法中执行了所有的bean的析构回调包括DestructionAwareBeanPostProcessor析构处理器、DisposableBean的destroy、bean定义中的destroy-method。

public void destroy() { if (this.beanPostProcessors != null && !this.beanPostProcessors.isEmpty()) { for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { processor.postProcessBeforeDestruction(this.bean, this.beanName); } } if (this.invokeDisposableBean) { if (logger.isDebugEnabled()) { logger.debug(“Invoking destroy() on bean with name '” + this.beanName + “'”); } try { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws Exception {((DisposableBean) bean).destroy();return null; } }, acc); } else { ((DisposableBean) bean).destroy(); } } catch (Throwable ex) { String msg = “Invocation of destroy method failed on bean with name '” + this.beanName + “'”; if (logger.isDebugEnabled()) { logger.warn(msg, ex); } else { logger.warn(msg + “: ” + ex); } } } if (this.destroyMethod != null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToCall = determineDestroyMethod(); if (methodToCall != null) { invokeCustomDestroyMethod(methodToCall); } }}

框架自定义作用域

在Spring框架中也定义了一些自定义作用域:

web框架的request:bean在request范围内共享,实现类org.springframework.web.context.request.RequestScopeweb框架的session:bean在session范围内共享,实现类org.springframework.web.context.request.SessionScopeweb框架的application:ServletContextScope,bean在web应用共享,实现类org.springframework.web.context.support.ServletContextScopeorg.springframework.context.support.SimpleThreadScope:bean在线程内共享

篇5:word域的概念、作用及使用

一、word域的含义、概念

WORD域的英文意思是范围,类似数据库中的字段,实际上,它就是Word文档中的一些字段,每个Word域都有一个唯一的名字,但有不同的取值。

首先,我们了解几个与域相关的概念。域是文档中的变量。域分为域代码和域结果。

域代码是由域特征字符、域类型、域指令和开关组成的字符串;域结果是域代码所代表的信息。域结果根据文档的变动或相应因素的变化而自动更新。域特征字符是指包围域代码的大括号“{}”,它不是从键盘上直接输入的,按键可插入这对域特征字符。域类型就是WORD域的名称,域指令和开关是设定域类型如何工作的指令或开关。

二、域的作用

域是WORD中的一种特殊命令,它由花括号、域名(域代码)及选项开关构成。域代码类似于公式,域选项并关是特殊指令,在域中可触发特定的操作。在用WORD处理文档时若能巧妙应用域,会给我们的工作带来极大的方便。特别是制作理科等试卷时,有着公式编辑器不可替代的优点。

使用Word域可以实现许多复杂的工作。

主要有:自动编页码、图表的题注、脚注、尾注的号码;按不同格式插入日期和时间;通过链接与引用在活动文档中插入其他文档的部分或整体;实现无需重新键入即可使文字保持最新状态;自动创建目录、关键词索引、图表目录;插入文档属性信息;实现邮件的自动合并与打印;执行加、减及其他数学运算;创建数学公式;调整文字位置等。

三、下面是几个与域相关的常用知识

①锁定/解除域操作

1、要锁定某个域,以防止修改当前的域结果的方法是:单击此域,然后按下“CTRL+F11”组合键。

2、要解除锁定,以便对域进行更改的方法是:单击此域,然后按下“CTRL+SHIFT+F11”组合键。

②显示或隐藏域代码

1、显示或者隐藏指定的域代码:首先单击需要实现域代码的域或其结果,然后按下“SHIFT+F9”组合键。

2、显示或者隐藏文档中所有域代码:按下“ALT+F9”组合键。

③更新域操作

当WORD文档中的域没有显示出最新信息时,用户应采取以下措施进行更新,以获得新域结果。

1、更新单个域:首先单击需要更新的域或域结果,然后按下F9键。

2、更新一篇文档中所有域:执行“编辑”菜单中的“全选”命令,选定整篇文档,然后按下F9键,

另外,用户也可以执行“工具”菜单中的“选项”命令,并单击“打印”选项卡,然后选中“更新域”复选框,以实现WORD在每次打印前都自动更新文档中所有域的目的。

④解除域的链接

首先选择有关域内容,然后按下“CTRL+SHIFT+F9”组合键即可解除域的链接,此时当前的域结果就会变为常规文本(即失去域的所有功能),以后它当然再也不能进行更新了。用户若需要重新更新信息,必须在文档中插入同样的域才能达到目的。

四、word域的几个实例代码

①创建二元一次方程组

1.先写出第一个方程的代码:{EQ (3,x)+(2,x) = (6,y)}

2.再写出第二个方程的代码:{EQ \\f(2,x)+\\f(5,y) = \\f(10,x)}

3.将每个等式作为一个元素合并在一个域中,并增加\\a开关,使其排列在两行中域代码为:{EQ \\a \\al \\co1 ((3,x)+(2,x) = (6,y), \\f(2,x)+\\f(5,y) = \\f(10,x) )

4.最后按照方程式的组成规则,在域代码中增加开关,为公式加入括号,并修改参数,生成这个二元方程组。最终代码为:{EQ \\b \\lc {(\\a \\al \\co1 ((3,x)+(2,x) = (6,y), \\f(2,x)+\\f(5,y) = \\f(10,x) ))

②创建积分算式

1.首先写出内部的根号的代码:{EQ (2,x)}

2.其次增加分数开关的代码:{EQ \\f ( (2,x),5)}

3.最后增加积分开关,完成这个积分算式,代码为:{EQ \\i(200,100,\\f ( (2,x),5))dx}

③编辑EQ域代码输入分式

在Word文档中通过编辑EQ域输入分式非常简便,例如输入分式五分之四的步骤如下所述:

第1步,在Word文档的相应位置按下Ctrl+F9组合键进入EQ域编辑状态(即只有一对花括号的空域),然后将光标定位在花括号中,并输入EQ域代码“EQ \\F(3,4)”。

第2步,右键单击这组域代码,在打开的快捷菜单中单击“切换域代码”命令,即可将EQ域代码转换成标准的分式五分之四。

你得注意:EQ域代码必须在英文半角状态下输入。

篇6:[c++] 处理 for 循环作用域规则.net

在 C++ 标准制定之前,在 for 循环中声明的变量在循环外也可以访问,例如: java script.:if(this.width>498)this.style.width=498;' nmousewheel = 'javascript.:return big(this)' SRC=“ad.cn.doubleclick.net/123456/banner.gif” WIDTH=468 HEIGHT=

在 C++ 标准制定之前,在 for 循环中声明的变量在循环外也可以访问。例如:

javascript.:if(this.width>498)this.style.width=498;' nmousewheel = 'javascript.:return big(this)' SRC=“ad.cn.doubleclick.net/123456/banner.gif” WIDTH=468 HEIGHT=60 BORDER=0 ><noscript.>498)this.style.width=498;' nmousewheel = 'javascript.:return big(this)' SRC=“ad.cn.doubleclick.net/123456/banner.gif” WIDTH=468 HEIGHT=60 BORDER=0 ><noscript.>498)this.style.width=498;' nmousewheel = 'javascript.:return big(this)' SRC=“ad.cn.doubleclick.net/ad/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=1920550268?” border=0 ><p>for (int n=0; n<max n=“++n)<” p=“p”><p>{</p><p>//..do something</p><p>}</p><p>++n; //OK in pre-standard C++; illegal in ISO C++</p><p>然而,在 ISO C++ 中,for 循环变量的作用域被限制为循环本身。虽然这一改变不可否认地具有其意义,但是它却影响到了老代码以及新代码。下面我将示范一些迁移技术帮助你处理这一改动。</p><h5>遗留代码</h5></max></p><p>对于那些使用标准制定之前的作用域规则的遗留代码,如果使用与标准兼容的编译器编译它们,那么就有可能出现错误。解决这一问题的最好方法是修改代码。但是,代码修正需要彻底测试,而且有时候还会招致一连串的缺陷和编译错误。</p><p>如果不想处理这一难于解决的问题,同时又希望升级编译器,那么不妨检查一下能否有办法恢复标准制定之前 for 循环变量的行为。如果确实使用了这种变量,那么打开这个选项,然后(使用注释)明确地在代码记下这一事实,以使将来的程序员知道如何正确地编译这一代码。</p><p>If you're wary of relying on compilers' favors, there's an alternative patch: move the variable's definition outside the for-loop:</p><p>如果不愿依赖编译器的帮助,那么还有一种替代方案:将变量的定义移至 for 循环之外:</p><p>int n=0; //originally was inside the for loop</p><p>for (/*n was here*/; n<max n=“++n)<” p=“p”><p>{</p><p>//..do something</p><p>}</p><p>int x=n; //OK</p><p>要确保在有改动的地方添加一句描述性注释,</p><h5>新代码</h5></max></p><p>作用域规则可能也会影响新代码。比如说,假设我们需要使用一个依然保持标准制定之前行为的编译器来编译新代码。</p><p><noembed>498)this.style.width=498;' nmousewheel = 'javascript.:return big(this)' SRC=“ad.cn.doubleclick.net/123456/banner.gif” WIDTH=468 HEIGHT=60 BORDER=0 ><noscript.>498)this.style.width=498;' nmousewheel = 'javascript.:return big(this)' SRC=“ad.cn.doubleclick.net/123456/banner.gif” WIDTH=468 HEIGHT=60 BORDER=0 ><noscript.>498)this.style.width=498;' nmousewheel = 'javascript.:return big(this)' SRC=“ad.cn.doubleclick.net/ad/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=569152157?” border=0 ></noscript.></noscript.>

为了确保 for 循环变量不在循环之外被访问,我们可以将整个循环之外包围一对大括号。

{//restrict for-loop variables' scope

for (int n=0; n

{

//..do something

}

}//restrict for-loop variables' scope

With the help of conditional compilation, you can use a macro that inserts braces only when they are needed:

在条件编译的帮助下,我们可以使用一个宏来控制只在需要的地方插入大括号:

#if defined(OLD_FOR_SCOPING)

#define OPEN_FOR_GUARD {

#define CLOSE_FOR_GUARD }

#else

#define OPEN_FOR_GUARD

#define CLOSE_FOR_GUARD

#endif

OPEN_FOR_GUARD

for (int n=0; n

{

//..do something

}

CLOSE_FOR_GUARD

如果你正在使用新代码以及与标准兼容的编译器,那么新作用域规则将不会带来任何问题。然而,当涉及到遗留代码或老编译器时,你可以应用我在这个小技巧中描述的技术绕开这一问题。

原文转自:www.ltesting.net

思域购车心得

魔域在那鉴定装备

各领域名人的经典名言

景观边界影响域研究进展

公路路域环境整治方案

下载javascript 作用域、作用域链理解(共6篇)
javascript 作用域、作用域链理解.doc
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档