变量声明置顶规则、函数声明及函数表达式和函数的arguments属性初始化
一、变量声明和变量赋值:
if (!("a" in window)) {
var a = ;
}
alert(a);//a为?
你可能认为alert出来的结果是1,然后实际结果是“undefined”。要了解为什么,我们需要知道JavaScript里的3个概念:
1、所有的全局变量都是window的属性,语句 var a = 1;等价于window.a = 1; 可以用如下方式来检测全局变量是否声明:
"变量名称" in window
2、声明置顶规则:所有的变量声明都在范围作用域的顶部。JavaScript引擎首先会扫描所有的变量声明,然后将这些变量声明移动到顶部。所以等价于:
var a;//声明置顶
if (!("a" in window)) {
var a = ;
}
3、变量声明会被提前至顶部,但变量赋值不会,赋值仍在代码处赋值,在赋值之前均为undefined。
当变量声明和赋值在一起用的时候,JavaScript引擎会自动将它分为两部以便将变量声明提前,不将赋值的步骤提前是因为他有可能影响代码执行出不可预期的结果。
二、函数声明和函数表达式:
var a = ,
b = function a(x) {
x && a(--x);
};
alert(a);
这个题目看起来比实际复杂,alert的结果是1;这里依然有3个重要的概念需要我们知道。
1、函数声明也是提前的,所有的函数声明都在执行代码之前都已经完成了声明,和变量声明一样。
什么是函数声明?是如下这样的代码:
function functionName(arg1, arg2){
//函数体
}
什么是函数表达式?如下这样的代码是函数表达式。函数表达式,相当于变量赋值。
var functionName = function(arg1, arg2){
//函数体
};
函数声明与函数表达式区别:函数声明同变量声明一样会提前;但是,函数表达式没有提前,就相当于平时的变量赋值。
2、函数声明会覆盖变量声明,但不会覆盖变量赋值。
function value(){
return ;
}
var value;
alert(typeof value); //"function"
function value(){
return ;
}
var value = ;
alert(typeof value); //"number"
从代码1看到尽管变量声明在下面定义,但是变量value依然是function,也就是说这种情况下,函数声明的优先级高于变量声明的优先级,但如果该变量value赋值了,那结果就完全不一样了:该value赋值以后,变量赋值初始化就覆盖了函数声明。
3、执行上下文的关系:执行上下文分2个阶段:进入执行上下文和执行代码,在进入执行上下文的时候,创建变量对象里就已经有了:函数的所有形参、所有的函数声明、所有的变量声明。
三、函数的arguments属性初始化:
function b(x, y, a) {
arguments[] = ;
alert(a);
}
b(, , );
活动对象是在进入函数上下文时刻被创建的,它通过函数的arguments属性初始化。arguments属性的值是Arguments对象,Arguments对象是活动对象的一个属性,它包括如下属性:
- callee — 指向当前函数的引用
- length — 真正传递的参数个数
- properties-indexes (字符串类型的整数) 属性的值就是函数的参数值(按参数列表从左到右排列)。 properties-indexes内部元素的个数等于arguments.length.;properties-indexes 的值和实际传递进来的参数之间是共享的。
这个共享其实不是真正的共享一个内存地址,而是2个不同的内存地址,使用JavaScript引擎来保证2个值是随时一样的,当然这也有一个前提,那就是这个索引值要小于你传入的参数个数,也就是说如果你只传入2个参数,而还继续使用arguments[2]赋值的话,就会不一致,例如:
function b(x, y, a) {
arguments[] = ;
alert(a);
}
b(, );
这时候因为没传递第三个参数a,所以赋值10以后,alert(a)的结果依然是undefined,而不是10,但如下代码弹出的结果依然是10,因为和a没有关系。
function b(x, y, a) {
arguments[] = ;
alert(arguments[]);
}
b(, );
总结:
一、变量声明提前,变量赋值不提前。
二、函数声明也是提前的,但是函数表达式不会提前(仅相当于变量赋值)。
三、函数声明(优先级高)能覆盖变量声明,但是不能覆盖变量赋值。
四、执行上下文分进入执行上下文和执行代码2阶段。进入执行上下文的时候,函数的所有形参、所有的函数声明,所有的变量声明就都在变量对象里了。
五、函数的arguments属性初始化:arguments属性的索引值要小于传入参数的个数,那么其值和实际传参的值是共享的;若如果索引值大于传参个数,则不共享,即双方无关,互不影响。
变量声明置顶规则、函数声明及函数表达式和函数的arguments属性初始化的更多相关文章
- js中的函数声明置顶
函数声明置顶是指 js引擎在读取变量与声明式函数时,会优先读取,例如如下 var a = 1: function a(){}; console.log(a); //这里得到的为1,而不是该functi ...
- [置顶] lua 进阶3--lua文件中调用C++函数
前面讲了一下,C++读取lua文件中的变量,包括一维表.二维表这些,这节讲一下如何在lua文件中去调用C++函数 C++代码如下 #include <stdio.h> extern &qu ...
- [置顶] js中如何复制一个对象,如何获取所有属性和属性对应的值
在js中如何复制一个对象,例如如下一个js对象. 如果知道这个对象的所有属性自然就可以重新new一个,然后对每个属性赋值,就可以做到,但如果不知道呢?如何创建一个内容相同 的对象呢? var obj= ...
- js函数声明提升与变量提升
变量提升 变量提升: 在指定作用域里,从代码顺序上看是变量先使用后声明,但运行时变量的 “可访问性” 提升到当前作用域的顶部,其值为 undefined ,没有 “可用性”. alert(a); // ...
- jQuery实现表格行上移下移和置顶
jQuery实现表格行上移下移和置顶 我们在操作列表数据的时候,需要将数据行排列顺序进行调整,如上移和下移行,将行数据置顶等,这些操作都可以在前端通过点击按钮来完成,并且伴随着简单的动态效果,轻松实现 ...
- C# WPF 一直保持多个Topmost窗体的置顶顺序
原文:C# WPF 一直保持多个Topmost窗体的置顶顺序 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37862405/article/ ...
- wordpress调用置顶文章sticky_posts的三种方法
有时我们在开发wordpress时需要调用置顶文章sticky_posts,怎么调用呢?几种写法,有用到query_post的,有用到WP_Query,也有用到is_sticky(),下面随ytkah ...
- C++ 理解函数对象与lambda表达式
参考<21天学通C++>第21与第22章节,对函数对象进行介绍,同时通过lambda表达式这一匿名函数对象的简洁方式加深对函数对象的理解.本篇博文的主要内容是: (1) 函数对象的概念: ...
- JavaScript 中对变量和函数声明的“提前”
变量声明“被提前” JavaScript 的语法和 C .Java.C# 类似,统称为 C 类语法.有过 C 或 Java 编程经验的同学应该对“先声明.后使用”的规则很熟悉,如果使用未经声明的变量或 ...
随机推荐
- Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Could not create connection to database server.
报错信息:Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQL ...
- Android自动化页面测速在美团的实践
背景 随着移动互联网的快速发展,移动应用越来越注重用户体验.美团技术团队在开发过程中也非常注重提升移动应用的整体质量,其中很重要的一项内容就是页面的加载速度.如果发生冷启动时间过长.页面渲染时间过长. ...
- iOS Sprite Kit教程之编写程序以及Xcode的介绍
iOS Sprite Kit教程之编写程序以及Xcode的介绍 Xcode界面介绍 一个Xcode项目由很多的文件组成,例如代码文件.资源文件等.Xcode会帮助开发者对这些文件进行管理.所以,Xco ...
- [ 原创 ] Java基础3--Java中的接口
一.使用接口(interface)的目的 Java只支持单继承,即一个类最多只能继承一个直接父类,接口的主要功能就是可以实现类似于类的多重继承的功能. 二.接口的性质 1.接口具有继承性,即子接口可继 ...
- JavaScript 数据类型 (续)
JavaScript 对象 对象由花括号分隔.在括号内部,对象的属性以名称和值对的形式 (name : value) 来定义.属性由逗号分隔: var person={firstname:" ...
- 【漏洞预警】CVE-2017-8464 震网三代漏洞复现
早在6月13日,微软发布补丁修复编号为CVE-2017-8464的漏洞,本地用户或远程攻击者可以利用该漏洞生成特制的快捷方式,并通过可移动设备或者远程共享的方式导致远程代码执行,追溯到以前,NSA就承 ...
- 【BZOJ】4767: 两双手【组合数学】【容斥】【DP】
4767: 两双手 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1057 Solved: 318[Submit][Status][Discuss] ...
- python开发_tkinter_多级子菜单
在之前的blog中有提到python的tkinter中的菜单操作 python开发_tkinter_窗口控件_自己制作的Python IDEL_博主推荐 python开发_tkinter_窗口控件_自 ...
- hdu 4442 Physical Examination 贪心排序
Physical Examination Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- jmeter3.3—插件管理器的安装
一.介绍JMeter Plugins 一直以来, JMeter Plugins 为我们提供了很多高价值的JMeter插件,比如: 用于服务器性能监视的 PerfMon Metrics Collecto ...