js基础

文章目录

      • 1.变量的类型和计算
        • 类型
        • 计算-类型转换
      • 2.原型与原型链
        • 原型
        • 原型链
      • 3.作用域与闭包
        • 作用域
        • 闭包
      • 4.异步和单线宏任务微任务

1.变量的类型和计算

类型

数据类型

基本类型:number、undefined、string、boolean、symbol、
引用类型:array、function、object、null

值类型

它都是在栈中存储的,因为它占用空间小。
常见的值类型:undefined、number、string、boolean、symbol

引用类型

它会在堆中申请一个地址,把数据放在堆中,
栈中的变量指向的是地址。占用空间大,不方便管理。
常见的引用类型:object、array
特殊的引用类型:null、function

typeof运算符

它可以判断所有的值类型,还能判断函数,能识别引用类型(不能细分)

计算-类型转换

  1. 字符串拼接

+运算中有字符串,结果就是字符串拼接。

2.=====

===三等表示全等,判断左右两边对象或值是否类型相同且值相等。
==二等表示值相等。判断操作符两边对象或值是否相等类型可以不同,类型不同时,使用Number()转换成Number类型在进行判断。例外规则,null/undefined进行运算时不进行隐式类型转换。通常把值转为Boolean值,进行条件判断。Boolean(null)===Boolean(undefined)>false===false结果为true

  1. if语句和逻辑运算

所有基本类型中Boolean值是false的只有6个,分别是 : 0 NaN ’ ’ null undefined false
引用类型Boolean值全是true.

  • if语句中的判断
    if条件是单个值时,如果是truly值,条件成立, 如果是falsely值,条件不成立
  • 逻辑判断:
    逻辑与(&&)运算规则: 左侧为truly返回右侧,左侧为fasely返回左侧。
    逻辑或( | | )运算规则: 左侧为truley返回左侧,左侧为fasely返回右侧。

深拷贝

function deepClone(obj={
     }){
     
	// 判断是否为引用类型
	if(typeof obj!=='object'||obj==null){
     
		return obj
	}
	// 初始化返回结果
	let res
	if(obj instanceof Array){
     
		res=[]
	}else{
     
		res={
     }
	}
	for(let key in obj){
     
		// 保证 key 不是原型的属性
		if(obj.hasOwnProperty(key)){
     
			// 递归调用
			res[key]=deepClone(obj[key])
		}
	}
	// 返回结果
	return res
}

2.原型与原型链

原型

原型的关系

  • 每个class都有显示原型 prototype
  • 每个实例都有隐式原型__proto__
  • 每一个实例对象的隐式原型_ proto _属性指向自身构造函数的显式原型prototype
  • 每个prototype原型都有一个constructor属性,指向它关联的构造函数。
    js基础_第1张图片

原型链

获取对象属性时,如果对象本身没有这个属性,那就会去他的原型__proto__上去找,如果还查不到,就去找原型的原型,一直找到最顶层(Object.prototype)为止。Object.prototype对象也有__proto__属性值为null。
js基础_第2张图片

3.作用域与闭包

作用域

变量作用域:就是一个变量可以使用的范围。
js基础_第3张图片
上图,每一个红框代表一个作用域

作用域分为:

全局作用域
函数作用域
块级作用域(ES6 新增)

  • js中首先有一个最外层的作用域,全局作用域;
  • js中可以通过函数来创建一个独立作用域称为函数作用域,函数可以嵌套,所以作用域也可以嵌套;
  • es6中新增了块级作用域(大括号,比如:if{},for(){},while(){}…);
// 块级作用域  let const 
if(true){
     
	let x=100
}
console.log(x) //会报错

自由变量

概念: 当前作用域没有定义的变量

1.一个变量在当前作用域没有定义,但被使用了。
2.向上级作用域,一层一层查找,直到找到为止。
3.如果到全局作用域都没有找到,就会报错。
自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方。

作用域链

自由变量的向上级作用域一层一层查找,直到找到为止,最高找到全局作用域,就形成了作用域链。

变量提升 (预解析)

var声明的变量,function声明的函数存在变量提升 (函数比var优先级高)
let const 不会变量提升

闭包

1.函数作为返回值被返回

function create() {
     
	let a = 100
	return function () {
     
	 console.log(a)
	}
}
let fn = create()
let a = 200
fn() //100

2.函数作为参数被传递

function print(fn) {
     
	let a = 200
	fn()
}
let a = 100
function fn() {
     
	console.log(a)
}
print(fn) //100

垃圾回收机制

浏览器的 Javascript 具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。其原理是:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大并且GC时停止响应其他操作,所以垃圾回收器会按照固定的时间间隔周期性的执行。

只有函数内的变量才可能被回收
垃圾收集器必须跟踪到底哪个变量没用,对于不再有用的变量打上标记,以备将来收回其内存。通常情况下有两种实现方式:标记清除和引用计数。引用计数不太常用,标记清除较为常用。

  • 标记清除

    js中最常用的垃圾回收方式就是标记清除。当变量进入环境时,例如,在函数中声明一个变量,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

  • 引用计数

    引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加 1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减 1。当这个值的引用次数变成 0 时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾回收器下次再运行时,它就会释放那些引用次数为 0 的值所占用的内存。

this 指向

使用场景:

1.普通函数 ------- this指向调用者
2. call apply bind ------- 改变this的指向
3.对象方法 ------- this指向调用的对象
4.class ------- this指向调用它的构造函数
5.箭头函数 ------- this始终指向它父级的上下文

this取什么值是函数调用时确认的,不是在函数定义时确认的。

function fn1() {
     
	console.log(this)
}
fn1() // x:100
fn1.call({
      x: 100}) 

const fn2 = fn1.bind({
      x: 200})
fn2() // x:200

js基础_第4张图片

4.异步和单线宏任务微任务

宏任务和微任务

宏任务包括:setTimeout setInterval Ajax DOM事件
微任务:Promise async/await
微任务比宏任务的执行时间要早

同步

console.log(100)
alert(200)
console.log(300)
// 100 200 300

异步

console.log(100)
setTimeout(()=>{
     
	console.log(200)
},1000)
console.log(300)
// 100 300 200

两者的区别:
异步不会阻塞代码执行
同步会阻塞代码执行

使用场景:
网络请求(如:ajax请求)、定时任务(如:setTimeout)。
js基础_第5张图片
js基础_第6张图片
setTimeout:一次性定时器,只执行一次。
setInterval:间接性定时器,可执行多次。

你可能感兴趣的:(js)