js中的执行上下文,菜鸟入门基础。
console.log(a); //Uncaught ReferenceError: a is not defined
因为没有定义a所以报错了。
var a = 52;
console.log(a); //
有定义a,并且给a赋值了52所以打印a就是52。
console.log(a); //undefined
var a = 52;
虽然有定义a但是打印却在变量a的前面,那为什么不是报错而是打印出来的是undefined?因为在js执行代码之前,js会先获取到所有的变量并且把这些变量放置到js代码的顶部。(简称变量声明提前)
实际上,上面的代码是这样执行的:
var a;
console.log(a);
所以代码出来的就是undefined,那你是不是会疑问?我们给赋值给a的52到哪去了。虽然我前面说了js会事先获取所有的变量并且将这些变量放置到顶部,但是变量的赋值并不会事先执行,也就是说,你在哪声明的变量,这个变量的赋值就在哪执行。
var a;
console.log(a); //undefined
虽然声明了但没有赋值所有undefined
console.log(a);
function a(){
this.user = "追梦子";
}
为什么,可以事先就打印出函数a呢?因为函数的赋值在函数声明的时候就已经赋值了,结合上面我说的变量提前,那是不是就可以理解这句话了?
当然这只是一种情况,还有一种情况,稍后说。
function a(){
this.user = "追梦子";
}
console.log(a);
正常
a(); //Uncaught TypeError: a is not a function
var a = function(){
console.log(52);
}
为什么现在又不行了?因为现在的函数已经赋值给了变量a,现在它的执行过程和变量一样了,我们通常把这种函数赋值给变量的形式叫做函数表达式。
var a = function(){
console.log(52);
}
a(); //
正常
if(false){
var a = 1;
}
console.log(a); //undefined
之所以没有报错而是输出了undefined是因为变量存在预解析的情况,又因为js没有块级作用域,所以最后代码就成了这样
var a;
if(false){
a = 1;
}
console.log(a);
总结:
函数分为:函数声明和函数表达式。
函数声明--
function a(){
alert("追梦子博客");
}
函数表达式--
var a = function(){
alert("追梦子");
}
看似两段相同的语句,它们的执行顺序却截然不同,函数声明时的赋值行为是在函数创建的时候进行的,而函数表达式的赋值行为是在执行这句变量时进行的(因为它已经赋值给了变量所以我这里把它称为变量)。
不管是变量还是函数都会存在变量声明提前。
来看看几题有意思的js例题,加以理解。
var a = 1;
function b(){
console.log(a); //undefined
var a = 5;
}
b();
为什么打印的是undefined?
我们先来看看它的解析过程:
var a = 1;
function b(){
var a
console.log(a); //undefined
a = 5;
}
b();
变量提前了,那为什么不打印全局变量1呢?如果你有这个问题我猜你应该是JavaScript的新朋友,那我建议你看我的上一篇文章:
什么是作用域链,什么是原型链,它们的区别,在js中它们具体指什么?
在看完作用域链以后我相信你能够看懂这个例子。
我们一起来看看另外一题比较有难度的js面试题:
var a = 1;
function b() {
a = 120;
return;
function a() {}
}
b();
alert(a); //1;
如果你看了上面一题我相信你应该有种不知所措的感觉,这里现在为什么又是1了呢?
我把执行过程的代码写出来我相信你就懂了。
var a = 1;
function b() {
var a;
a = 120;
return;
function a() {}
}
b();
alert(a);
如果你正在js的进阶阶段肯定更闷了,你肯定会想我们不是写return了吗?return后面的代码不是不执行吗?为什么这里却影响了这段代码?
虽然return后面的代码不会被执行,但是在js预解析的时候(变量提升的时候)还是会把return后面的变量提前,所以我们这段代码因为变量提前所以函数里面的变量a就成了局部变量,因为函数外部是访问不了函数内部的变量所以就输出了1。
另外提两点,函数的arguments和函数名都是直接赋值的,也就是在这个函数解析的时候就会进行赋值。
如果你还是不理解建议多看几遍,另外如果你是js的新朋友一定要看什么是作用域链,什么是原型链,它们的区别,在js中它们具体指什么?这篇文章。
js中的执行上下文,菜鸟入门基础。的更多相关文章
- 进阶学习js中的执行上下文
在js中的执行上下文,菜鸟入门基础 这篇文章中我们简单的讲解了js中的上下文,今天我们就更进一步的讲解js中的执行上下文. 1.当遇到变量名和函数名相同的问题. var a = 10; functio ...
- 通俗易懂的来讲讲js的函数执行上下文
0.开场白 在平时编写JavaScript代码时,我们并不会和执行上下文直接接触,但是想要彻底搞懂JavaScript函数的话,执行上下文是我们绕不过去的一个知识点. 1.执行上下文栈 JavaScr ...
- JS进阶之---执行上下文,变量对象,变量提升
一.结构顺序大体介绍 JavaScript代码的整个执行过程,分为两个阶段,代码编译阶段与代码执行阶段. 编译阶段由编译器完成,将代码翻译成可执行代码,这个阶段作用域规则会确定. 执行阶段由引擎完成, ...
- js中的执行环境及作用域
最近在面试时被问到了对作用域链的理解,感觉当时回答的不是很好,今天就来说说js中的作用域链吧. 首先来说说js中的执行环境,所谓执行环境(有时也称环境)它是JavaScript中最为重要的一个概念.执 ...
- JS中的执行环境和作用域
window 是最大最外围的执行环境,然后每个函数都有自己的执行环境.JS代码是从上到下执行的,单纯的用语言描述可能会有点绕,而且不大直观.我们看着代码来 console.log('global be ...
- Promise对象及它在js中的执行顺序
关于Promise对象的学习及它的执行顺序 学习阮一峰老师的ES6入门后的记录 1.promise的定义 promise是一个对象,通常包裹着一个异步操作,promise对象提供一些接口的方法,返回一 ...
- js作用域与执行环境(前端基础系列)
一.作用域(what?) 官方解释是:"一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域." 单从文字理解比较难懂,举个栗子: ...
- 在JS中统计函数执行次数与执行时间
假如想统计JS中的函数执行次数最多的是哪个,执行时间最长的是哪个,该怎么做呢? 1. 统计函数执行次数 2. 统计函数执行时间 3. 如何控制函数的调用次数 4. 如何控制函数的执行时间 一.统计函数 ...
- JS中的执行机制(setTimeout、setInterval、promise、宏任务、微任务)
1.执行机制 JS 是单线程的,处理 JS 任务(程序)只能一个一个顺序执行,所以 JS 中就把任务分为了同步任务和异步任务.同步的进入主线程先执行,异步的进入Event Table并注册函数,当指定 ...
随机推荐
- JAVA编程中的类和对象
1:初学JAVA,都知道JAVA是面向对象的编程.笔者这节开始说说类和对象.(实例仅供参考,如若复制粘贴记得修改包名和类名,避免出错) 学习JAVA的快捷键,Alt+/代码补全功能,其实此快捷键启动了 ...
- 详解Bootstrap表单组件
表单常见的元素主要包括:文本输入框.下拉选择框.单选框.复选框.文本域.按钮等.下面是不同的bootstrap版本: LESS: forms.less SASS: _forms.scss boot ...
- php-fpm的配置和优化
php-fpm的安装目录 下面是我的平时的环境搭建php的各种安装目录,大家的基本也差不多. centos等linux平台 /usr/local/php/php /usr/local/php/etc/ ...
- .NET开发中经常用到的扩展方法
整理一下自己经常用到的几个扩展方法,在实际项目中确实好用,节省了不少的工作量. 1 匿名对象转化 在WinForm中,如果涉及较长时间的操作,我们一般会用一个BackgroundWorker来做封装 ...
- strcmp传入nil导致崩溃
现象:连接电脑可以正常启动程序,不连接电脑启动程序就崩溃. 崩溃信息: BSXPCMessage received error for message: Connection invalid HW k ...
- CMD command
过滤字符串查找:netstat -aon|findstr "80"
- ubuntu 16.04 vnc server
安装方法 https://help.ubuntu.com/community/VNC/Servers#vino 系统默认自带的,通过搜索Remote Desktop来找到它 配置好之后,设定一下密码 ...
- 【转】Java之WeakReference与SoftReference使用讲解
Java 2 平台引入了 java.lang.ref 包,其中包括的类可以让您引用对象,而不将它们留在内存中.这些类还提供了与垃圾收集器(garbage collector)之间有限的交互. 1.先“ ...
- mybatis oracle java.sql.SQLException: 流已被关闭问题
/** * 按照页码取值(从current_page页开始,每页page_size条) * @param key * @param params * @param current_page * @pa ...
- 绘制n边形:用两个以上的控件来控制矩形的颜色、大小、位置及空实心(程序代写)
绘制n边形:用两个以上的控件来控制矩形的颜色.大小.位置及空实心.(n由键盘输入) package lzy.di9zhang; import java.awt.BorderLayout;import ...