1. 原始类型有哪几种?null 是对象嘛?
在 JS 中,存在着 6 种原始值,分别是:
- boolean
- null
- undefined
- number
- string
- symbol
首先原始类型存储的都是值,是没有函数可以调用的,比如undefined.toString()
此时你肯定会有疑问,这不对呀,明明'1'.toString()是可以使用的。其实在这种情况下,'1'已经不是原始类型了,而是被强制转换成了String类型也就是对象类型,所以可以调用toString函数。
除了会在必要的情况下强转类型以外,原始类型还有一些坑:
其中 JS 的number类型是浮点类型的,在使用中会遇到某些 Bug,比如0.1 + 0.2 !== 0.3,但是这一块的内容会在进阶部分讲到。string类型是不可变的,无论你在string类型上调用何种方法,都不会对值有改变。
另外对于null来说,很多人会认为他是个对象类型,其实这是错误的。虽然typeof null会输出object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000开头代表是对象,然而null表示为全零,所以将它错误的判断为object。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。
js深入
1 数据
-
1 存在 内存中
-
1.1 内存的分类
- 栈:计算机分配的空间
- 1 名 —> 变量名
- 2 地 —> 空间 —> 值 —> 基本类型数据 | 地址
- 堆:程序员自己创造的空间
- 1 IP —> 指向空间所在的位置
- 2 地 —> 空间 —> 值 —> 对象
- 栈:计算机分配的空间
-
1.2 对象分类
- 函数对象
- 1 静态属性 只能是函数对象调用
- 2 原型属性 函数实例的对象使用
- 3 由Function创建的
- 普通对象
- 1 是由函数对象创建的
- 2 有原型对象 ‘obj.__proto===function.prototype’
- 函数对象
-
1.3 对象是私有的 不可以相互访问 原型对象除外
-
1.4 在原型链上所有属性对象都可以访问
-
1.5 Object.prototype js中所有的对象都可以获取
-
2 什么时候用 —> 使用变量
从内存中读取数据的方式
优化内存的方式:减少读取内存的次数
- 2.1 什么时候读取变量 —> 代码执行的时候
- 2.2 代码如何使用变量 —> 变量的使用规则
- 2.3 变量的使用规则是怎么形成的 —> 作用域以及作用域链
- 2.4 作用域怎么形成的 —> 执行上下文创建的
- 2.5 为何会有执行上下文 —> 为了运行一段段js代码
- 2.6 js如何运行 —> 执行上下文栈中运行的
- 请看执行
// 读同一个字段;读内存读了两次
window.token ? window.token : 'token'; // 黑马常用
// 优化 一个字段 读内存读了一次
window.token || 'token'
执行
- 进程 与 线程
- 浏览器一个tab一个进行
- 一个进程下面有多个线程 例如:js引擎执行线程 渲染dom线程 发送http请求线程 线程在程序结束就会销毁
- 进程在关闭tab销毁
相信大家经常会听到 JS 是单线程执行的,但是你是否疑惑过什么是线程?
讲到线程,那么肯定也得说一下进程。本质上来说,两个名词都是 CPU工作时间片的一个描述。
进程描述了 CPU 在运行指令及加载和保存上下文所需的时间,放在应用上来说就代表了一个程序。线程是进程中的更小单位,描述了执行一段指令所需的时间。
把这些概念拿到浏览器中来说,当你打开一个 Tab 页时,其实就是创建了一个进程,一个进程中可以有多个线程,比如渲染线程、JS 引擎线程、HTTP 请求线程等等。当你发起一个请求时,其实就是创建了一个线程,当请求结束后,该线程可能就会被销毁。
上文说到了 JS 引擎线程和渲染线程,大家应该都知道,在 JS 运行的时候可能会阻止 UI 渲染,这说明了两个线程是互斥的。这其中的原因是因为 JS 可以修改 DOM,如果在 JS 执行的时候 UI 线程还在工作,就可能导致不能安全的渲染 UI。这其实也是一个单线程的好处,得益于 JS 是单线程运行的,可以达到节省内存,节约上下文切换时间,没有锁的问题的好处。当然前面两点在服务端中更容易体现,对于锁的问题,形象的来说就是当我读取一个数字 15 的时候,同时有两个操作对数字进行了加减,这时候结果就出现了错误。解决这个问题也不难,只需要在读取的时候加锁,直到读取完毕之前都不能进行写入操作。
执行栈
- 是一个存储函数
执行上下文
变量对象(预编译阶段)
作用域链
this
闭包
查询窗口滚动条的位置
//以一个对象的x和y属性的方法返回滚动条的偏移量
function getScrollOffsets(w) {
//使用指定才窗口,如果不带参数则使用当前窗口
w = w || window;
//除了IE8及更早的版本以外,其它的浏览器都能用
if (w.pageXOffset != null) return {x: w.pageXOffset, y:w.pageYOffset};
//对标准模式下的IE,或任何浏览器
var d = w.document;
if (document.compatMode == "CSS1Compat")
return {x:d.documentElement.scrollLeft, y:d.documentElement.scrollTop};
//怪异模式下的浏览器
return { x: d.body.scrollLeft, y: d.body.scrollTop };
}
判定一个元素尺寸和位置最简单的方法是调用它的getBoundingClientRect()方法。
这个方法是在IE5中引入的。而现在所有的浏览器都实现 了,它不需要参数,返回一个有left,right,top,bottom的属性对象。left和top表示左上角的x和y坐标。right和bottom属性表示元素右下角的x和y坐标。