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

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. JAVAEE——宜立方商城10:使用freemarker实现网页静态化、ActiveMq同步生成静态网页、Sso单点登录系统分析

    1. 学习计划 1.使用freemarker实现网页静态化 2.ActiveMq同步生成静态网页 2. 网页静态化 可以使用Freemarker实现网页静态化. 2.1. 什么是freemarker ...

  2. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之部署master/node节点组件(四)

    0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 1.部署master组件 ...

  3. Outlook数据提取工具readpst

    Outlook数据提取工具readpst   Outlook是Windows常用的邮件客户端.它将用户的信息保存到.pst文件中,如邮件.约会.日历.联系人等信息.为了便于查看这些信息,Kali Li ...

  4. keystone 认证深度研究分析

    一.Keystone Token深度概述 Keystone作为OpenStack项目基础认证模块,目前支持的token类型分别是uuid.pkiz.pki.fernet. 首先,简要叙述一下这四种类型 ...

  5. OpenStack计费项目Cloudkitty系列详解(一)

    云计算是一种按需付费的服务模式,虽然OpenStack前期在计量方面走了些“弯路”,但现在的ceilometer.gnocchi.aodh.panko项目的稳步并进算是让其峰回路转.然而,目前来看Op ...

  6. 1go基本语法

    // week1 project main.go//导入一个包(目录) package main //导入方法 import "fmt" //createMessage函数(参数, ...

  7. 机器学习之路:python 集成分类器 随机森林分类RandomForestClassifier 梯度提升决策树分类GradientBoostingClassifier 预测泰坦尼克号幸存者

    python3 学习使用随机森林分类器 梯度提升决策树分类 的api,并将他们和单一决策树预测结果做出对比 附上我的git,欢迎大家来参考我其他分类器的代码: https://github.com/l ...

  8. SQL Server 无日志文件附加数据库

    CREATE DATABASE DBname ON (FILENAME = 'D:\SalesData\DBname_data.mdf') FOR ATTACH_REBUILD_LOG ; GO 简单 ...

  9. curl多文件上传

    发送: header('Content-type:text/html; charset=utf-8'); //声明编码//模拟批量POST上传文件$url = 'http://test.cm/rece ...

  10. 如何在java中跳出当前多重嵌套循环?有几种方法?

    如何在java中跳出当前多重嵌套循环?有几种方法? - 两种方法   - 1.在外层循环定义标记          ok:          for(int i=0;i<100;i++){    ...