~~~
v; // v打印出为undefined
var v = 1; // 如果没有这行定义,上面一行会报错 Uncaught ReferenceError: v is not defined(…)
~~~
这是为什么呢?
定义在下面应该还没有生效啊,怎么感觉就像是提前定义了一样呢。
实际上js在解释执行代码时,代码就相当于被转换成这样了:
~~~
var v; // 只是申明了,所以下面v会打印出undefined
v;
var v = 1;
~~~
这就是申明提前,在函数中也是如此。
~~~
function foo() {
console.log(a);
var a = 1;
console.log(a);
}
foo(); // 先打印出undefined后打印出1
~~~
其实受“申明提前”的作用,这段代码相当于:
~~~
function foo() {
var a;
console.log(a);
var a = 1;
console.log(a);
}
foo();
~~~
>[info] 注意:在语句中申明提前会将声明提前到语句的最上面,在函数中申明会被你提前到函数的最顶部。
明白了吧。
* * * * *
### 由申明提前引发的BUG
```javascript
// 全局的变量
viewport = document.querySelector("meta[name=viewport]");
console.log(viewport) // meta Element
function scale () {
console.log(viewport); // 意外吧,竟然是undefined
if (viewport == null) {
var viewport = metaEl = document.createElement('meta');
} else {
viewport.content = str;
}
// 后面要用viewport,所以才想着即使没有viewport也要定义,哪成想到申明提前这么厉害啊
console.log(viewport.content);
}
```
奇怪了吧,viewport在全局环境中可以打印出来,在函数中就打印未定义了,按道理说,函数中应该能找到全局的变量啊。
其实都是提前申明惹的祸。
这里诡异奇葩的是,根本没执行到这儿来的地方,也会被拿出来提前申明,无语了吧。
所以问题找到了,优化代码逻辑,不要这么写就能避免这个坑了。
```javascript
// 全局的变量
viewport = document.querySelector("meta[name=viewport]");
console.log(viewport) // meta Element
function scale () {
console.log(viewport); // undefined
if (viewport == null) {
var metaEl = document.createElement('meta');
} else {
viewport.content = str;
}
// 既然所有变量都会申明提前,那么即使没执行到metaEl定义部分也不会出错
var _viewport = viewport || metaEl;
console.log(_viewport.content);
}
```
* * * * *
last update:2018-7-21 05:51:42
- 开始
- 微信小程序
- 获取用户信息
- 记录
- HTML
- HTML5
- 文档根节点
- 你真的了解script标签吗?
- 文档结构
- 已经落后的技术
- form表单
- html实体
- CSS
- css优先级 & 设计模式
- 如何编写高效的 CSS 选择符
- 笔记
- 小计
- flex布局
- 细节体验
- Flex
- Grid
- tailwindcss
- JavaScript
- javascript物语
- js函数定义
- js中的数组对象
- js的json解析
- js中数组的操作
- js事件冒泡
- js中的判断
- js语句声明会提前
- cookie操作
- 关于javascript你要知道的
- 关于innerHTML的试验
- js引擎与GUI引擎是互斥的
- 如何安全的修改对象
- 当渲染引擎遇上强迫症
- 不要使用连相等
- 修改数组-对象
- 算法-函数
- 事件探析
- 事件循环
- js事件循环中的上下文和作用域的经典问题
- Promise
- 最佳实践
- 页面遮罩加载效果
- 网站静态文件之思考
- 图片加载问题
- 路由及转场解决方案
- web app
- 写一个页面路由转场的管理工具
- 谈编程
- 技术/思想的斗争
- 前端技术选型分析
- 我想放点html模板代码
- 开发自适应网页
- 后台前端项目的开发
- 网站PC版和移动版的模板方案
- 前后端分离
- 淘宝前后端分离
- 前后端分离的思考与实践(一)
- 前后端分离的思考与实践(二)
- 前后端分离的思考与实践(三)
- 前后端分离的思考与实践(四)
- 前后端分离的思考与实践(五)
- 前后端分离的思考与实践(六)
- 动画
- 开发小技巧
- Axios
- 屏幕适配
- 理论基础
- 思考
- flexible.js原理
- 实验
- rem的坑,为什么要设置成百分比,为什么又是62.5%
- 为什么以一个标准适配的,其它宽度也能同等适配
- 自适应、响应式、弹性布局、屏幕适配
- 适配:都用百分比?
- 番外篇
- 给你看看0.5px长什么样?
- 用事实证明viewport scale缩放不会改变rem元素的大小
- 为什么PC端页面缩放不会影响rem元素
- 究竟以哪个为设备独立像素
- PC到移动端初试
- 深入理解px
- 响应式之栅格系统
- 深入理解px(二)
- 一篇搞定移动端适配
- flex版栅格布局
- 其他
- 浏览器加载初探
- 警惕你的开发工具
- JS模块化
- webpack
- 打包原理
- 异步加载
- gulp
- 命名规范
- 接口开发
- sea.js学习
- require.js学习
- react学习
- react笔记
- vue学习
- vue3
- 工具、技巧
- 临时笔记
- 怎么维护好开源项目
- 待办
- 对前端MVV*C框架的思考
- jquery问题
- 临时
- 好文
- 节流防抖