=============================1、JS中函数带括号和不带括号的区别=====================
================================================================================
(资料地址:https://www.zhihu.com/question/31044040)
demo1 demo2实际上是指针,你只需要记住,函数名就是指针就可以了。
例子:function fun(){
return 5
}
var a=funvar b=fun()
JS中我们把以上代码加粗的部分叫做函数,函数是一种叫做function引用类型的实例,
因此函数是一个对象。对象是保存在内存中的,函数名则是指向这个对象的指针。
var a = fun 表示把函数名fun这个指针拷贝一份给变量a,
但是这不是指函数本身被复制了一份。就好比,地图上上海市(对应函数对象)只有一个,
但指向上海市的路标(对应指针)有很多,而且你还可以继续添加(复制)无数个指向上海市的路标,
但上海市本身不会被复制。如果函数名后面加上圆括号就表示立即调用(执行)这个函数里面的代码(花括号部分的代码)。
另外函数声明和函数表达式在私有作用域写法方面也会在函数体后面加圆括号表示立即调用这个函数,
题主可以参看JS的模仿块级作用域的知识。
=============================2、JS中基础类型和引用类型的区别========================
==================================================================================
(资料地址:http://blog.sina.cn/dpool/blog/s/blog_6fd4b3c10101d0va.html?vt=4)
两种类型:
1. ECMAScript变量包含两种不同类型的值:基本类型值、引用类型值;
2. 基本类型值:指的是保存在栈内存中的简单数据段;
3. 引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象;
两种访问方式:
4. 基本类型值:按值访问,操作的是他们实际保存的值;
5. 引用类型值:按引用访问,当查询时,我们需要先从栈中读取内存地址,然后再顺藤摸瓜地找到保存在堆内存中的值;
=============================3、关于JS中的闭包的例子,理解闭包的神奇之处!============
================================================================================
(资料地址:https://www.toutiao.com/a6532059457667465731/?tt_from=mobile_qq&utm_campaign=client_share×tamp=1521116397&app=news_article&utm_source=mobile_qq&iid=27598554260&utm_medium=toutiao_android)
demo如下:
<script>
function f1(){
var n=0;
function f2(){
n = n+1;
console.log(n);
}
return f2;
}
var result = f1();
result();
result();
result();
</script>
代码中,外部函数 f1 只执行了一次,变量 N 设为 0 ,并将内部函数 f2 赋值给了变量 result 。
由于外部函数 f1 已经执行完毕,其内部变量N应该在内存中被清除,
然而事实并不是这样:我们每次调用 result 的时候,发现变量 N 一直在内存中,
并且在累加。为什么呢?这就是闭包的神奇之处了!
附加疑问:有了以上1和2知识点的理解了之后,你就会慢慢理解,为什么函数f1中内部return后面返回的是f2而不是f2()了
(注意若是f2则会报错:Uncaught TypeError: result is not a function)
=================4、JS中栈内存和堆内存的概念的理解(2中有简单的提到)=================
===============================================================================
(资料地址:http://blog.csdn.net/zuiziyoudexiao/article/details/72934603)
下面这篇资料讲解的很到位!(注意3小条中的括号中的一句话,很形象很准确!一下就理解了!!)
首先JavaScript中的变量分为基本类型和引用类型。基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象。
1、基本类型
基本类型有Undefined、Null、Boolean、Number 和String。这些类型在内存中分别占有固定大小的空间,他们的值保存在栈空间,我们通过按值来访问的。
2、引用类型
引用类型,值大小不固定,栈内存中存放地址指向堆内存中的对象。是按引用访问的。(自己加的:比如数组和对象)如下图所示:栈内存中存放的只是该对象的访问地址,在堆内存中为这个值分配空间。由于这种值的大小不固定,因此不能把它们保存到栈内存中。但内存地址大小的固定的,因此可以将内存地址保存在栈内存中。
这样,当查询引用类型的变量时, 先从栈中读取内存地址, 然后再通过地址找到堆中的值。
对于这种,我们把它叫做按引用访问;当我们看到一个变量类型是已知的,就分配在栈里面,比如INT,Double等。其他未知的类型,比如自定义的类型,因为系统不知道需要多大,所以程序自己申请,这样就分配在堆里面。基本类型大小固定,引用类型大小不固定,分开存放使得程序运行占用内存最小。
3、栈内存:存放基本类型。 堆内存:存放引用类型(在栈内存中存一个基本类型值保存对象在堆内存中的地址,用于引用这个对象。)
4、基本类型在当前执行环境结束时销毁,而引用类型不会随执行环境结束而销毁,只有当所有引用它
的变量不存在时这个对象才被垃圾回收机制回收。
看一个例子:
var x = {name:"aaa"};//初始化一个对象
var obj1 = x;
var obj2 = x; //obj1,obj2指向同一个引用类型
obj1.name = "bbb"; //在原引用上修改对象属性,x,obj,obj2的name属性值均改变
obj1 = {name:"bbb"} //给obj1赋了一个新的引用,所以只有obj的name值改变了