今天也有很努力的在赚猫粮钱
如若文章存在错误或不足,望理解并帮我指出,感激不尽
数据类型,存储方式
其中原始类型又分为七种类型,分别为:
boolean
number
string
undefined
null
symbol
bigint
对象类型分为两种,分别为:
Object
Function
原始类型存储在栈上,对象类型存储在堆上,但是它的引用地址还是存在栈上
var let const
ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
var:
var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。变量可以重复定义。(现在在开发中已经很少会使用)。
let:
变量需要声明后才可以使用,声明的变量存在块级作用域。
let不允许在相同作用域内,重复声明同一个变量。
const:
const 声明之后必须马上赋值,否则会报错。
const 简单类型一旦声明就不能再更改,复杂类型(数组、对象等)指针指向的地址不能更改,内部数据可以更改。
let、const使用场景:
let使用场景:变量,用以替代var。
const使用场景:常量、声明匿名函数、箭头函数的时候。
作用域
-
全局作用域
-
函数作用域
-
块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
第一种场景,内层变量可能会覆盖外层变量。
第二种场景,用来计数的循环变量泄露为全局变量。
注意ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。
作用域链
在javascript的学习中,执行环境、作用域是2个非常非常重要和基本的概念。
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象 (variable object),环境中定义的所有变量和函数都保存在这个对象中。虽然我们编写的代码无法访问这个对象,但解析器会处理数据时会在后台使用它。
在代码在一个环境执行时,会创建变量对象的一个 作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。整个作用域链是由不同执行位置上的变量对象(Variable Object)按照规则所构建一个链表。
作用域链的前端,始终都是当前执行的代码所在环境的变量对象。下一个变量对象来自包含(外部)环境,而下一个变量对象则来自下一个包含对象。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链的最后一个对象。
原型 原型链
原型
每个实例对象都有一个 constructor
属性,指向它的构造函数。
每个函数对象(包括构造函数) 都有一个 prototype
属性,指向函数的原型对象。这个原型对象的 constructor
属性,指向函数本身。
每个对象都有一个 [[prototype]]
私有属性,指向它的构造函数的原型对象,但这个属性是不允许访问的。某些浏览器(例如 Chrome)提供 __proto__
属性用于访问 [[prototype]]
私有属性
构造函数的 constructor
属性都是指向 Function
,__proto__
属性都是指向 Function.prototype
。因为构造函数都是通过 new Function
来创建的,它们都是 Function
的实例对象,包括 Function
和 Object
除 Object
外,其它构造函数的 prototype
属性的 __proto__
属性都是指向 Object.prototype
。 而 Object
的 prototype
属性的 __proto__
属性指向 null
原型链
所有对象都有 __proto__
属性,并且这个 __proto__
属性指向一个原型对象。
因为原型对象也是对象,这个原型对象也有 __proto__
属性,我们把这种关系称为原型链
当需要访问一个对象的属性时,首先从该对象开始查找,如果能够找到,那么到此返回。
如果没有找到,就在该对象的 __proto__
属性指向的原型对象中继续查找,如果能够找到,那么到此返回。
如果没有找到,那么一直往上查找原型对象,直至 __proto__
属性指向 null,也就是原型链的顶端
若原型链上的所有原型对象都没有该属性,则返回 undefined。
解决跨域问题 & 同源
明白跨域问题前,先了解一下同源策略,什么是同源,同源就是协议,域名,端口全都需要相同,有任何一项不同就会引起跨域问题:
-
Cookie、LocalStorage和IndexDB无法读取
-
DOM无法获取
-
AJAX请求不能发送
前端解决跨域的方式有很多,我常用如下1、2条:
-
nginx反向代理
反向代理的优点: 1. 保护网络安全,所有请求都先经过代理服务器。 2. 负载均衡,把请求转发到压力较小的服务器。(内置策略,扩展策略可以了解一下) 3. 可以做一些中间层设置,比如缓存静态资源。 复制代码
-
config 中配置 proxyTable 中 changeOrigin : true
-
jsonp (只支持GET请求)
-
CORS
-
postMessage
-
node
-
webSocket
-
iframe
call apply bind
call()、apply()、bind()是Function.prototype上的方法,所有函数都可以调用,它们的第一个参数都是this的指向对象。
call方法可以将调用函数执行,并将this 指向第一个参数,后续其他参数将会全部传递给调用函数使用。
all()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。
在非严格模式下,如果call()和apply()的第一个参数是null或者undefined,那么this的指向就是window全局变量。
bind返回的是方法。
总结:
call()、apply()和bind()都是可以用来改变this指向,可借助它们实现继承;
call()与apply()区别在于参数不一样,如果想一目了然表达形参和实参的对应关系,用call()比较合适;
bind()是返回一个新函数,可供以后调用,而apply()和call()是立即调用,并返回结果
箭头函数的特点
-
用 => 代替 function,语法简单
-
不绑定 this,箭头函数体内的 this 永远指向的是定义时所在的对象。 (建有函数中不会创建自己的this,而是从自己的作用域的上一层继承)
-
不支持call apply bind
-
不绑定arguments (普通函数通过arguments获取传入的参数值)
-
支持嵌套
-
不能使用箭头函数作为构造函数,没有prototype属性
JS常用内置对象和方法
javascript事件循环 / event Loop / JS执行机制
讲解事件循环前先提一下单线程和多线程
• 单线程:单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。
• 多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
浏览器组成原理
HTTP HTTPS HTTP2
ajax axios
javascript回收机制
垃圾回收有两种实现方式,分别是标记清除和引用计数
标记清除:当变量进入执行环境时标记为“进入环境”,当变量离开执行环境时则标记为“离开环境”,被标记为“进入环境”的变量是不能被回收的,因为它们正在被使用,而标记为“离开环境”的变量则可以被回收
引用计数:统计引用类型变量声明后被引用的次数,当次数为 0 时,该变量将被回收。
内存泄漏
内存泄露就是不再被需要的内存, 由于某种原因, 无法被释放。
造成内存泄漏的方式:
-
全局变量造成内存泄露
-
未销毁的定时器和回调函数造成内存泄露
-
闭包造成内存泄露
-
DOM引用造成内存泄露