下面所有的东西都不为堆高我的编程能力,所以我只是把对JS的认识用最粗鄙的语言进行讲解和记录,所以,阅读需谨慎!
JS执行
-
JS在执行之前会先进行编译。这第一句话都可能被我带坏了,毕竟市面上都是说JS是动态的解释执行语言,但那又如何?!知道JS在执行之前是先进行‘编译’的就好。且看下面
console.log(a);//undefined //把它复制到js文件里,并对下面一行打上断点,看控制台输出的是什么?undefined!说明在执行前进行了‘编译’ //提醒:最好是在没有安装插件的浏览器环境执行,要不控制台可能会出现因插件带来的异常信息 console.log(b);//Uncaught ReferenceError: b is not defined var a='a';
对于上面的代码还要注意:
JS存在变量提升的行为,即会把声明的变量提升到当前执行上下文的最顶端
所以console.log(a)
输出的是undefined
,注意!是undefined!不是a!变量提升提升的是变量的声明,而不是先执行var a='a'
这句话。而console.log(b)
却会抛出一个异常,虽然都是‘没定义’但一定要分清a是undefined
,b是not defined
是变量没有声明,是一个会阻塞JS执行的ReferenceError
异常
另外ReferenceError
异常同作用域判断失败相关 -
堆栈
不要问我什么是堆栈,我也不知道,不过我通常这么理解:堆,是存放数据的堆内存;栈就是用来执行的盒子容器(真的会被我带坏,哈哈哈),这里讲栈,其实通俗来说,栈就是堆栈。栈遵循先进后出,后进先出的特点,进出的是执行上下文,最先进入的全局上下文,并且在浏览器关闭时才被弹出
-
JS虽说是单线程的,但也能实现一些异步特性,进入堆栈的就有这么两种情况:同步情况和异步情况
同步情况当然是当下进入
异步情况常见的包括两种:延时和事件监听,事件监听常如AJAX,当他们的回掉函数执行时才创建其执行的上下文放入栈中:
setTimeout(function () { console.log(1); }); console.log(2);
是不是先打印的2?虽然这里并没有设置时长,但依旧先执行
console.log(2)
,这便是堆栈的机制,JS执行的机制表现
作用域
这个东西简单、老生常谈,但如果稍不留意还是会经常出错,然而这里我只说几点不直观的演示和讲解
-
变量提升会先提升函数然后才是变量,见下
fa();//fa fb();//Uncaught TypeError: fb is not a function //fb()的异常错误代表变量已被声明且作用域判断成功,但因还没定义造成的用方错误 function fa() { console.log('fa'); } var fb=function () { console.log('fb'); };
所以,为了避免混乱,也是推荐的规范写法,以后的函数声明还是用变量声明吧。
-
循环结构和条件结构的用花括号包裹的代码块并不会创建新的作用域,也不是真正的代码块,如下
(function(){ for(var i=0;i<6;i++){ if(i===3){ var b=i; return false; } console.log(b);//三次undefined } })();
注意:ES6的
let
const
已做改进
类型
不是说数据类型哈!
JS包括基本类型和引用类型
基本类型即直接存放在内存中的,可以直接访问的,其包括
number
string
boolean
null
undefined
-
引用类型即存放在内存中的对象,实际保存的是一个指针,一个引用,其包括
object
array
function
,且看下面的代码var a=[1,2,3,4]; var b=a; b[0]=6; console.log(a);//[6, 2, 3, 4]
弱类型
这个没什么好说的,但异常往往总是因此发生,哪怕不是什么复杂的工程。所以对纯前端尤其值得一提,不仅要知道怎么进行数据类型的转换更要清楚的知道你当下在操作的是什么数据类型。另外,建议使用全判断,即如==替换为===
函数
依旧不负责任的说:我不知道js一切皆对象是对是错,该怎么表述它才是对的或错的,但除原始值(或者上面说的基本类型)是对象是毫无疑问的,也正式如此,才让函数能有多种身份:普通函数、对象的方法、对象的构造器、对象
—————————————————————占位————————————————————————
其他
function免费配送了除了this之外的arguments参数,这个在我们不清楚该函数传过来那些参数时比较有用
JS的数组其实是对象,是
arraylike
的对象,所以for等循环不仅可以操作数组也可以操作对象,所以也可以给数组添加非整型下标,另外数组的长度是根据整型作为下标的最大值+1得来的
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。