一、变量声明和变量赋值:

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对象是活动对象的一个属性,它包括如下属性:

  1. callee — 指向当前函数的引用
  2. length — 真正传递的参数个数
  3. 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属性初始化的更多相关文章

  1. js中的函数声明置顶

    函数声明置顶是指 js引擎在读取变量与声明式函数时,会优先读取,例如如下 var a = 1: function a(){}; console.log(a); //这里得到的为1,而不是该functi ...

  2. [置顶] lua 进阶3--lua文件中调用C++函数

    前面讲了一下,C++读取lua文件中的变量,包括一维表.二维表这些,这节讲一下如何在lua文件中去调用C++函数 C++代码如下 #include <stdio.h> extern &qu ...

  3. [置顶] js中如何复制一个对象,如何获取所有属性和属性对应的值

    在js中如何复制一个对象,例如如下一个js对象. 如果知道这个对象的所有属性自然就可以重新new一个,然后对每个属性赋值,就可以做到,但如果不知道呢?如何创建一个内容相同 的对象呢? var obj= ...

  4. js函数声明提升与变量提升

    变量提升 变量提升: 在指定作用域里,从代码顺序上看是变量先使用后声明,但运行时变量的 “可访问性” 提升到当前作用域的顶部,其值为 undefined ,没有 “可用性”. alert(a); // ...

  5. jQuery实现表格行上移下移和置顶

    jQuery实现表格行上移下移和置顶 我们在操作列表数据的时候,需要将数据行排列顺序进行调整,如上移和下移行,将行数据置顶等,这些操作都可以在前端通过点击按钮来完成,并且伴随着简单的动态效果,轻松实现 ...

  6. C# WPF 一直保持多个Topmost窗体的置顶顺序

    原文:C# WPF 一直保持多个Topmost窗体的置顶顺序 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37862405/article/ ...

  7. wordpress调用置顶文章sticky_posts的三种方法

    有时我们在开发wordpress时需要调用置顶文章sticky_posts,怎么调用呢?几种写法,有用到query_post的,有用到WP_Query,也有用到is_sticky(),下面随ytkah ...

  8. C++ 理解函数对象与lambda表达式

    参考<21天学通C++>第21与第22章节,对函数对象进行介绍,同时通过lambda表达式这一匿名函数对象的简洁方式加深对函数对象的理解.本篇博文的主要内容是: (1) 函数对象的概念: ...

  9. JavaScript 中对变量和函数声明的“提前”

    变量声明“被提前” JavaScript 的语法和 C .Java.C# 类似,统称为 C 类语法.有过 C 或 Java 编程经验的同学应该对“先声明.后使用”的规则很熟悉,如果使用未经声明的变量或 ...

随机推荐

  1. zoj-1610线段树刷题

    title: zoj-1610线段树刷题 date: 2018-10-16 16:49:47 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道简单的线段树区间染色问 ...

  2. OSI、TCP、IP、UDP 这些都是啥??

    一个大大的问号首先抛出,计算机之间是如何进行通信的? 计算机网络是通过传输介质.通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来,实现资源共享和数据传输的系统. 网络协议就是数据按照一定的 ...

  3. C++运算符重载 模板友元 new delete ++ = +=

    今天的重载是基于C++ 类模板的,如果需要非类模板的重载的朋友可以把类模板拿掉,同样可以参考,谢谢. 一.类模板中的友元重载 本人喜好类声明与类成员实现分开写的代码风格,如若您喜欢将类成员函数的实现写 ...

  4. Date日期

    当我们只需要一个日期时,或从系统取得,或从数据库查询,都可以放入一个Date对象. 当我们需要对Date进行详细分析,获取其中的年月日分秒各个部分的信息,用Calendar类. 当我们需要对一个字符串 ...

  5. type与instance区别

    class Foo(object): pass class Bar(Foo): pass obj = Bar() # isinstance用于判断,对象是否是指定类或其派生类的实例 print(isi ...

  6. thinkphp5使用redis

    1.设置应用配置文件config.php type可以是很多分类File.Redis等等 2.thinkphp5使用redis新建application/index/controller/index. ...

  7. SKLearn数据集API(一)

    注:本文是人工智能研究网的学习笔记 数据集一览 类型 获取方式 自带的小数据集 sklearn.datasets.load_ 在线下载的数据集 sklearn.datasets.fetch_ 计算机生 ...

  8. GIT(5)----常用命令:新分支,切换,删除,远程推送,标签,日志

    常用命令 1.新分支 创建新分支:git branch <branch_name> 创建分支并切换到新的分支上:git checkout -b <branch_name> 2. ...

  9. Linux中文件/文本的中文乱码解决方法

    Linux显示在Windows编辑过的中文就会显示乱码是由于两个操作系统使用的编码不同所致.Linux下使用的编码是utf8,而Windows使用的是gb18030.因此,解决Linux打开txt/c ...

  10. vue父子组件使用时遇到的一个问题

    子组件一定要写在父组件之前,例如: //子vue,这里遇到一个坑,那就是子vue一定要写在父vue前面,不然会报错. Vue.component('todo-item', { template: $( ...