JavaScript前导知识

163 阅读5分钟

操作系统常识

开机

  • 操作系统存放在硬盘中(c盘)
  • 按下开机键,主板通电,读取主板上的内存(里面写死了开机程序)
  • 开机程序会把硬盘中的操作系统加载进内存

操作系统

  • 首先加载操作系统内核
  • 启动初始化进程,编号为1,每一个进程都有编号
  • 启动系统服务,文件,安全,联网
  • 等待用户登录
  • 登录后会开启一个终端,运行shell,用户就可以通过终端,终端通过shell和操作系统对话

打开浏览器

  • 双击chrome,运行chrome.exe文件
  • 开启chrome进程,作为主进程
  • 主进程会开启其他辅助进程(网络服务,gpu)
  • 每开启一个网页就可能开启一个子进程

浏览器

  • 发起请求,下载HTML,解析HTML。下载css,解析css,渲染界面,下载js,解析js,执行js
  • 浏览器为了完成以上功能需要什么模块:用户界面,渲染引擎,js引擎,存储
  • 上面的功能模块处于不同线程
  • 如果js代码需要修改css,它不能直接修改,他需要通过线程直接的通信来通知渲染引擎
  • 进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。
  • 边解析执行js代码
  • 解析就是读,去理解代码什么意思
  • 下载HTML,解析到第3行看到css,开始下载css,所以边解析html边下载css

js引擎

  • chrome用的是v8引擎,c++编写
  • node.js用v8
  • 编译:引擎把js代码翻译成机器可以理解的字节码和机器码
  • 优化:改写代码使代码优秀
  • 执行:执行上面字节码和机器码
  • 回收:把js用完的内存回收,例如代码中声明的变量
  • 尽量不要在js里修改css属性,让css实现动画效果,让js实现交互,可以使用js代码加上类名active

执行js代码

  • 浏览器提供API:window,document,settimeout
  • 发起请求到js代码下载好了,js代码在内存中运行

内存图

  • 内存中存放操作系统,chrome开启进程,之后开启辅助进程和子进程,下载好js代码后放到代码区在不知道什么区存放字符表
  • 每种浏览器分配不一样
  • stack(栈):每个数据按顺序存放,比较低效如果补充数据时会很麻烦
  • heap(堆):每个数据随机存放

stack和heap

  • 数据分为对象和非对象
  • 非对象都在stack,数字,字符,布尔
  • 对象都在heap,数组和函数是对象

对象和变量

  • window变量和window对象不是一个东西
  • window变量是一个容器存放window对象的地址
  • window对象是heap里面的一堆数据

window

  • 浏览器提供window,很多东西挂在了window上
  • console=window.console
  • document=window.document
  • object=window.Object
  • Array=window.Array
  • 开头大写的都是函数,Object,Array

原型链

  • JS创建之初就已经给出了window.Xxx.prototype对象,它储存了xxx对象的共同属性,称为原型。
  • window.Object.prototype对象储存了object对象的共同属性
  • window.Array.prototype对象储存了array对象的共同属性
  • 每一个xxx对象都有一个隐藏属性__proto__,这个隐藏属性储存了window.Xxx.prototype的地址,也就是这个隐藏属性指向了window.Xxx.prototype这个对象,也就是隐藏属性指向共同属性,指向原型。
  • 比如obj是一个Object,obj的对象有一个隐藏属性__proto__,它指向window.Object.prototype对象。
  • 比如a是一个Array,a的对象有一个隐藏属性__proto__,它指向window.Array.prototype对象。

创建了obj和obj2,两个的隐藏属性都引用了object和array的prototype,那么修改obj隐藏属性中的tostring,obj2是否改变?

  1. 下图情况修改a,那么b会被篡改,栈中a,b指向堆中#103
  2. obj和obj2对象在栈中占据了两块内存,指向了堆中#999和#1024,##999和##1024中的隐藏属性指向了堆中另一块内存#13,这个时候修改obj.tostring,只会修改隐藏属性中的tostring,一层可以篡改二层不可以,因为隐藏属性就是存了一个地址而已

  • obj有一个隐藏属性
  • 隐藏属性存储了Object.prototype对象的地址
  • obj.toString()发现obj .上没有toString
  • 就去隐藏属性对应的对象里面找
  • 于是就找到了Object.prototype.toString
  • prototype和__proto__都存着原型的地址,只不过prototype挂在函数上,__proto__挂在每个新生成的对象上。
  • 我们现在只研究函数(大写字母开头)的prototype和新生对象(小写字母开头)的_ proto _
  • 共有属性我们可以读,但是修改了的话只能存放到自己的对象里,放不进共有属性里面,也就是我们改不了共有属性,只能修改共有属性在我们上面的值。
  • 所有对象包括Array和Object都有一个隐藏属性,他们的祖先是Object的隐藏属性,Object的隐藏属性的隐藏属性是null
  • Object 是一个全局函数,可以用来生成对象,var obj = new Object() ,可以简写成 var obj = {};而 object 什么也不是,除非我声明一个 var object