JS 基础

142 阅读4分钟

JS的理解

JS的基本概念

诞生

1995年,Brend Eich开发

  1. 借鉴C语言的基本语法
  2. 借鉴Java语言的数据类型和内存管理
  3. 借鉴Scheme语言,将函数提升到“第一公民”(first class)的地位
  4. 借鉴Self语言,使用原型(prototype)的继承机制

发展

wohugb.gitbooks.io/javascript/…

  1. Mocha>1995.9 LiveScript>1995.12 JavaScript
  2. 1997年6月,第一版ECMAScript发布
  3. 1999年12月,第三版ECMAScript发布
  4. 2009年12月,第五版ECMAScript发布
  5. 2009年,Ryan创建了Node.js
  6. 2010年,Isaac基于node.js写出了npm
  7. 2015年6月,第六版ECMAScript发布

浏览器的进程模型(以chrome为例)

image.png

JS特性

  • 单线程
  • 动态、弱类型
  • 面向对象、函数式
  • 解释类语言、JT
  • 安全、性能差
  • ······

JS线程和GUI线程

-1283823451.jpg

JS语言种类

-1283763940.jpg

面向对象和函数式

uTools_1682736652462.png

数据类型

image.png

const a = {
  name:'zq';
}    //复杂的数据类型,在JavaScript中存的是内存地址
const b = a;  //将a的地址给了b
b.name = '111111';

//在JavaScript中,基础的数据类型,赋予的是值,并不是内存地址
const str = '11';
let newStr = str;
newStr = '22';

console.log(a,b,str,newStr)  //

//在JavaScript中,复杂的数据类型原始值可以被改变,在基础的数据类型中不可以被改变
const arr = [1,2];
arr.push(3);  //将3放入数组arr中

const str = 'strstr';
str.slice(0,2);

console.log(arr,str)    //[1,2,3]  strstr

变量的可访问性和可见性

静态作用域,通过它就能够预测代码在执行过程中如何查找标识符

全局作用域

var corpary ="Bytecance";

function showCompany() {
cansole.log(corpary);
}
showCorpany()

函数作用域

var company "Bytedance";
Function showCorpany () {
	company = "douyin";
	console.log(company);
}
showConpany ()

块级作用域

{
	const company ="Bytedance";
	console.log(1,company);
}
console.log(2,company);

变量提升

console.log('company',company);
console.log('dep',dep);
console.log('myname',myname);
showInfo();
show();

const company "Bytedance";
let dep="边缘云";
var myname ="zhangqi";
function showInfo () {
	console.log(company,dep,myname);
	console.log(myname);
var show = function () {
	console.log(myname);
}
  • var有变量提升
  • let、consti没有变量提升,提前访问会报错
  • function函数可以先调用再定义
  • 赋值给变量的函数无法提前调用
  • image.png

JS是怎样执行的

总览图

image.png

转换过程

image.png

执行上下文

当JS引擎解析到可执行代码片段(通常是函数调用)的时候,就会先做一些执行前的准备工作,这个准备工作,就叫做“执行上下文(execution context简称EC)”,也叫执行环境

image.png

全局执行上下文

全局执行上下文:代码开始执行时就会创处,将他压执行栈的栈底,每个生命周期内只有一份

函数执行上下文

函数执行上下文:当执行一个函数时,这个函数内的代码会被编译,生成变量环境、词法环境等,当函数执行结束的时候该执行环境从栈顶弹出

image.png

var scop ='global';
func () ;
console.log(company);
function func () {
	var funcVar 'func';
	console,log('这是个函数',funcVar);
}
var company='字节跳动';

Eval执行上下文

执行步骤

创建执行上下文的时候做了什么?

  1. 绑定This
  2. 创建语法环境
  • 词法环境:基于ECMAScript代码的词法嵌套结构来定义标识符和具体变量和函数的关联。一个词法环境由环境记录器和一个可能的引用外部词法环境的空值组成
  1. 创建变量环境
  • 变量环境:变量环境和词法环境的一个不同就是前者被用来存储函数声明和变量(It和const)绑定,而后者只用来存储var变量绑定
  • Outer:指向外部变量环境的一个指针

代码示例

const company ="Douyin";
function testCompany () {
	const company "Tiktok";
	function testCompany1 () {
		const company "Bytedance"
		function testCompany2 () {
			return company;
    }
	return testCompany2()
  }
	return testCompany1();
}
console.1og(testCompany())

image.png

内存示意图

变量与堆栈

image.png

指针ESP

image.png

JS的进阶知识点

闭包

示例代码

function showName () {
	const company "Bytedance";
	const dep=“边缘云";
	const name "zhangqi";
	console.log('company',company);
	return function (){
		console.log(dep);
		return name
	}
}
const getName showName();
console.log(getName());

示意图

image.png

缺点:内存不容易被回收。

This

示例代码

function shouName () {
	console.log(this)
}

const personObj = {
	name:'zhangsan';
	dep:'边缘云';
	showName () {
	console.log(this.name)
	},
}
personObj.showName()
const getName = person.showName
getName()

//此处为构造函数
function ShowName () {
  this.name = 'zhangqi';
}
const getName = new ShowName()

示意图

image.png

垃圾回收

image.png

总结

  1. JS 是单线程的,但是Render进程里面有多个线程。
  2. JS线程和GUI线程互斥,执行大的计算任务会导致页面卡顿。
  3. 基础数据类型存在栈上,复杂数据类型存在堆上。
  4. const、let没有变量提升、提前使用会报错。
  5. JS也有编译的过程,执行之前会生成执行上下文。
  6. 一个执行上下文包括:变量环境、语法环境、this。
  7. 变量环境里面有一个指向外部函数执行上下文的指针,形成了作用域链。
  8. 全局执行上下文只有一份。
  9. this和执行上下文绑定。