Js的语言类型
Js是一种 弱类型,动态 的语言。
动态是什么意思呢,动态是在使用变量前不需要确定变量的类型,在给变量赋值的时候确定变量的值。
弱类型是什么呢,弱类型是支持 隐形转换 的语言。举个例子给一个变量赋为整数,再给这个变量赋为字符串,系统会把这个变量的类型自动从int转为String。
a=1
a="String"-----系统会自动把a的类型改为字符串类型
Js的数据类型
Js的数据类型有很多,从储存的方式可以分为 基础类型 和 引用类型 ,我写了一些数据类型,前7种都是基础类型,后三种都是应用类型。 栈很小,基础类型因为一般比较小,所有直接放在栈中,引用类型一般都比较大所以放在堆中,只在栈中放一个地址,指向堆中放的数据。
let a = 1
a = 'hello'
a = true
a = null
a = undefined
a = Symbol(1)
a = 123n
a = []
a = {}
a = function () {}
- 基础类型 是直接储存在栈上,不用储存在堆上
- 引用类型 是在栈上存储一个地址,地址指向在堆上存储的对象
这里从内存的角度解释两种类型的生成过程
function foo() {
var a = 1
var b = a
var c = { name: 'zzz' }
var d = c
}
foo()
- foo在全局作用域中被调用,生成foo的函数作用域
- 在foo的函数作用域上,直接给基础类型的变量赋值
- 给引用类型的变量在堆上申请地址,把对象放入,然后返回一个地址给引用类型的变量
为什么要把栈设计的很小,不把所有的东西都放进去呢
因为栈是用来维护函数的调用关系的,如果设计的过大,程序员就可能肆无忌惮的,调用函数,让一个函数调用链变得非常长,函数之间的切换就会变得很慢。就像把一个口袋设计的过长,往里面放东西,掏东西的话就会很麻烦。而且如果你把你的函数调用关系写的栈都放不下,更应该反省自己是不是在写屎山代码。
写个编程题
写出下列代码的输出结果
function foo() {
var myname = '牛哥'
let test1 = 1
const test2 = 2
var innerBar = {
setName: function (name) {
myname = name
},
getName: function () {
console.log(test1);
return myname
}
}
return innerBar
}
var bar = foo()
bar.setName('羊哥')
console.log(bar.getName());
首先分析下这串代码,在函数foo中创建了一个对象,在对象中构建两个函数并返回对象,构成闭包。然后再通过对象中的函数访问闭包。画一个图分析下
- 这是在var bar = foo()执行之后的内存空间,foo函数被调用完后销毁,里面被调用的变量生成闭包,生成的对象放在堆中,地址返回给bar
- bar.setName('羊哥'),根据作用域链的关系找到闭包中的myname改为羊哥
- console.log(bar.getName());输出闭包中的text1和myname
最后输出1,羊哥