js基础了解

JS中基本数据类型与引用数据类型

JS的七大数据类型:Number, String, Boolean, Undefined , Null ,Symbol,Object
基本数据类型:Number,String,Boolean,Undefined, Null,Symbol
引用数据类型:Object , Array, Function

其中的5种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值;
而引用类型是的值是保存在内存中的对象。
与其它语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。
在操作对象时,实际上是在操作对象的引用,因此引用类型的值是按引用访问的

总结:
基本类型值与引用类型值具有以下特点
基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中
从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本
引用类型的值是对象,保存在堆内存中
包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针
从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此最终两个变量最终都指向同一个对象
确定一个值是哪种基本类型可以使用typeof操作符,而确定一个值是哪种引用类型可以使用instanceof操作符

浅谈堆和栈的理解

内存的存储机制

  • 我们的每一个数据都是存储在内存里面
  • 我们的内存被分为了两个地方
  1. 栈内存(基本数据类型) => 直接存储在栈里面
  2. 堆内存(复杂数据类型)=> 数据存储在堆里面,地址存储在栈里面

简单谈一谈关于值传递与引用传递

值传递:传递的是基本数据类型的数据(数据不会发生改变)
引用传递:传递的是对象(数组、对象)对象存储在堆空间中,自身可以发生改变

js变量存储有栈存储和堆存储

基本数据类型的变量存储在栈中。
引用数据类型的变量存储在堆中 ,地址存在栈中,当访问引用类型变量时,先从栈中读取地址,在根据地址到堆中取出数据。当访问基础类型变量时,直接从栈中取值。

js中的强制类型转换与隐式类型转换

隐式类型转换:== != - * / % *= /= -= %=
强制类型转换:Number parseInt():取整转换 parseFloat()

JS中null和undefined的区别

typeof null => obj

typeof undefined => undefined

  • null是一个表示"无"的对象,转为数值时为0;
  • undefined是一个表示"无"的原始值,转为数值时为NaN。

undefined
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。

null
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。

谈谈你对NaN的理解

  • Not a Number 不是一个数字

  • NaN仅仅代表不是一个数字,自身和自身都不相等(NaN != NaN)

  • 如何判断NaN isNaN===>如果是NaN,返回true,否则返回false Number.isNaN( )

  • NaN的数据类型是number

说下i++与++i之间的区别

i++: 先使用,在加1
++i: 先加1,在使用

JS延迟加载的方式有哪些

JS延迟加载,也就是等页面加载完成之后再加载js文件,js延迟加载有助于提高页面加载速度

一般有以下几种方式:

1.defer属性

<script src='test.js' defer='defer'></script>

2.async属性

<script src='test.js' async></script>

3.动态创建DOM方式

4.使用jquery的getScript方法

$.getScript('outer.js',function(){//回调函数,成功获取文件后执行的函数
	console.log('脚本加载完成')
})

5.使用setTimeout延迟方法

6.让js最后加载

懒加载和预加载

懒加载

什么是懒加载

  • 懒加载也叫延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。用户滚动到他们之前,可视区域外的图像不会加载,这与图像预加载相反,在长网页上使用懒加载将使网页加载得更快。
    在某些情况下,他还可以帮助减少服务器负载。常适用于图片很多,页面很长的电商网站中

为什么要用懒加载

  • 能提升用户的体验,不妨设想下,用户打开淘宝长页面的时候,如果页面上所有的图片都需要加载,由于图片数目较大,等待时间很长,用户难免会心生抱怨,这就严重影响用户体验,减少无效资源的加载,这样能明显减少服务器的压力和流量,也能够减少浏览器的负担
  • 防止并发加载得资源过多会阻塞js的加载,影响网站的正常使用。

懒加载的原理

  • 首先将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在data-original属性中,当页面滚动的时候需要去监听scroll事件,在scroll事件的回调中,判断我们的懒加载的图片是否进入可视区域,如果图片在可视区内将图片的 src 属性设置为data-original 的值,这样就可以实现延迟加载。
  • 懒加载是前端性能优化方法之一,他可以减少请求数或延迟请求数。
  • 实现原理:先加载一部分数据,当触发某个条件时利用异步加载剩余的数据。
  • 实现方法:
    1.延迟加载,使用setTimeout或setInterval进行延迟加载
    2.条件加载,当触发某个条件时才开始异步加载数据
    3.可视区域加载,即只加载用户所看到的区域,这个主要监控滚动条来实现。

预加载

什么是预加载

  • 资源预加载是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会直接被用到。
    预加载简单来说就是讲所有所需的资源提前请求加载到本地,这样后面在需要用到的时候就直接从缓存取资源

为什么要用预加载

  • 在网页全部加载之前,对一些主要内容进行加载,以提供用户更好的体验,减少等待时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间展现为一片空白,直到所有内容加载完毕,这样影响用户体验。

懒加载和预加载对比

两者都是提高页面性能有效的办法,两者主要的区别是一个提前加载,一个是延缓甚至不加载
懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力

节流防抖

场景:在工作中,我们可能回碰到这样的问题:
用户在搜索的 时候,在不停的敲字,如果每敲一个字我们就调用一次接口,接口调用频繁,卡住。
用户在阅读文章的时候,我们需要监听用户滚动到了哪个标题,但是每滚动一下就监听,那样会太过频繁从而占内存,如果再加上其他的业务代码,就卡住了。所以这时候,我们及用到了防抖与节流了。

防抖

防抖——触发高频事件后 n 秒后函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间;

例如:有个输入框,输入之后会调用接口,获取联想词。但是,因为频繁调用接口不太好,所以我们在代码中使用防抖功能,只有在用户输入完毕的一段时间后,才会调用接口,出现联想词。

function debounce(fn) {
    
    
	let timeout = null
	// 创建一个标记用来存放定时器的返回值
	return function() {
    
    
		clearTimeout(timeout)
		// 每当用户输入的时候把前一个 setTimeout clear 掉
		timeout = setTimeout(() => {
    
    
		// 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
		fn.apply(this, arguments)
	}, 500)
}}function sayHi() {
    
    
console.log('防抖成功')}var inp = document.getElementById('inp')inp.addEventListener('input',debounce(sayHi)) // 防抖

节流

节流:指定时间间隔内只会执行一次任务。

那么,节流在工作中的应用?

  1. 懒加载要监听计算滚动条的位置,使用节流按一定时间的频率获取。
  2. 用户点击提交按钮,假设我们知道接口大致的返回时间的情况下,我们使用节流,只允许一定时间内点击一次。
function throttle(fn) {
    
    
	let canRun = true // 通过闭包保存一个标记
	return function() {
    
    
	if (!canRun) return
	// 在函数开头判断标记是否为 true,不为 true 则 return
	canRun = false // 立即设置为 false
	setTimeout(() => {
    
    
	// 将外部传入的函数的执行放在 setTimeout 中
	fn.apply(this, arguments)
	// 最后在 setTimeout 执行完毕后再把标记设置为 true(关键) 表示可以执行下一次循环了。当定时器没有执行的时候标记永远是 false,在开头被 return 掉
	canRun = true
	}, 500)
}}function sayHi(e) {
    
    
	console.log(e.target.innerWidth,e.target.innerHeight)}
	window.addEventListener('resize',throttle(sayHi))

同源策略

同源:同一个来源
在ajax请求服务器文件时。保证 协议 域名 端口号完全一致情况下,才可以访问服务器数据。
同源策略是浏览器的一个行为标准,保证用户使用该浏览器时 数据的安全性,ajax受同源策略的影响,不能实现跨域访问数据。
跨域:在一个域 访问 另一个域的数据

​如何实现跨域访问数据

有四种方式
1.前端方式 possMessage
2.纯后端方式 CORS
3.前后端结合 Jsonp
4.webSocket

jsonp

jsonp: json with padding 是ajax的一种数据访问格式 通过这种数据访问格式,跨域实现 跨域访问数据(限于get)

jsonp跨域原理
1、动态创建一个script标签,添加到body中
2、设置script标签的src属性值,属性值就是一个接口
3、通过接口上的某个参数向服务器传递一个函数 通过这个回调函数 接收服务器返回的数据
通过jsonp格式获取的服务器数据大多数都是object类型
应用场景:
在网上经常看到别人的blog中在用jsonp模仿360和百度进行跨域拿数据,这两者就是典型的跨域请求案例。又比如在近期开发中前端部分用的是vue.js进行开发,所以跟后台进行交互的时候就可以通过跨域进行通信,正好用的jsonp(折腾 一番之后,最终没有用这种方式,后面会说到)另外,qq空间大部分用的都是。

优缺点

jsonp优点:
完美解决在测试或者开发中获取不同域下的数据,用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。简单来说数据的格式没有发生很大变化。

jsonp缺点:

这里主要讲jsonp的缺点,也就是我上面说的没有用这个的原因

  • 1.jsonp只支持get请求而不支持post请求,也即是说如果想传给后台一个json格式的数据,此时问题就来了,浏览器会报一个http状态码,415错误,告诉你请求格式不正确,这让我很头疼(在登录注册中需要给后台传一大串数据),如果都用参数的形式拼接在url后面的话不太现实,后台取值也会显得繁琐。
  • 2.在登录模块中需要用到session来判断当前用户的登录状态,这时候由于是跨域的原因,前后台的取到的session是不一样的,那么就不能就行session来判断.
  • 3.由于jsonp存在安全性问题(不知qq空间的跨域是怎么解决的,还是另有高招?)
    后来考虑到上面的一系列问题,采用的是后台进行设置允许跨域请求(但还是存在缺陷的,实质上还是跨域,如上面说的session问题)
    .Header set Access-Control-Allow-Origin *
    为了防止XSS攻击我们的服务器, 我们可以限制域,比如
    Access-Control-Allow-Origin: http://blog.csdn.net
  • 安全防范:
    1.防止callback参数意外截断js代码,特殊字符单引号双引号,换行符存在风险.
    2.防止callback参数恶意添加script标签,造成xss漏洞
    3.防止跨域请求滥用,阻止非法站点恶意调用

​cors跨域

用于服务器的跨域请求数据

​promise

​promise : 承诺
promise对象有三种状态 : pending 进行中
resolved 已解决
rejected 失败
promise对象特点

事件触发机制是什么样的?在什么时候用捕获,什么时候用冒泡?

JS中事件执行的整个过程称之为事件流,分为三个阶段:事件捕获阶段,事件目标处理函数,事件冒泡。

  • 1.微软提出了名为事件冒泡的事件流。事件冒泡可以形象的比喻为把一颗石头投入水中,
    泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,
    直到document对象
  • 2.网景提出另一种事件流事件捕获,与事件冒泡相反,事件会从最外层开始发生,
    直到最具体的元素。
  • 3.网景和微软曾经的战争还是比较火热的,当时,网景主张捕获方式,微软主张冒泡方法,
    后来W3C采用了折中的方式,平息了战火,制定了统一的标准,先捕获后冒泡

当某个元素触发某个事件,顶级对象document就会发出一个事件流,顺着dom的树节点向触发他的目标节点流去,直到达到目标元素,这个向下查找目标的过程是事件的捕获阶段,这个过程与事件相应的函数是不会触发的。当到达目标阶段,便会执行绑定在此元素上,与事件响应的函数,即为事件目标处理函数阶段。最后,从目标元素起,再次依次往顶层元素对象传递,途中如果有节点绑定了同名事件,这些事件所对应的函数,在此过程中便称之为事件冒泡。
通常情况下,事件相应的函数四在冒泡阶段执行的。addEventListener的第三个参数默认为false,
表示冒泡阶段执行(为true的时候,表示捕获阶段执行)

使用e.stopPropgation()或e.cancelBubble = true(IE)可以阻断事件向当前元素的父元素冒泡。

  • 在事件冒泡或者事件捕获阶段处理并没有优劣之分,但是由于事件冒泡的事件流模型被所有主流浏览器兼容,从兼容性角度来说还是建议使用事件冒泡模型。

异步、回调函数与面向对象

  • 异步:异步是在主线程执行完后回调队列里的函数,所以所有的异步都有回调函数并且只要是异步,那么就一定应该提供一个回回调函数,方便程序的列队,属于异步的有事件,promise,定时器。
  • 回调函数: 回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调, 回调,回调,就是回头调用的意思。主线程的事先干完,回头再调用传进来的那个函数。
  • 面向对象:
    1)构造函数:构造对象用的,构造出来的对象我们叫它Ceo的实例化对象(构造函数就是创建对象的工具; 创建可定制对象的工具)
    2)构造函数的执行流程:
A、立刻在堆内存中创建一个新的对象
B、将新建的对象设置为函数中的this
C、逐个执行函数中的代码
D、将新建的对象作为返回值

3)this:分两种:构造函数中的this指向构造函数的实例化对象,不可更改;普通函数中的this指向调用者,一般用bind方法固定指向。

注意:
	1)js单线程特质 就是上一行代码不执行完 下一行代码不执行;
    2)JS之中存在非常多的速度极慢的IO,我们会对这样的程序进行一个列队操作;
    3)当函数对象本身的属性或方法与原型的属性或方法同名的时候:
    
    1、默认调用的是函数对象本身的属性或方法.
    2、通过原型增加的属性或方法的确是存在的.
    3、函数对象本身的属性或方法的优先级要高于原型的属性或方法.
    
在函数里有一个属性prototype(原型)
	由该函数创建的对象默认会连接到该属性上
    prototype 与 _proto_ 的关系
    _proto_是站在对象角度来说的
    prototype 是站在构造函数角度来说的

http和https的区别

  • 1、HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加
    密的,安全性较好。
    使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证
    书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign
    等。
  • 2、HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和
    服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一
    共是 12 个包。
  • 3、http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
  • 4、HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗
    费服务器资源。

原型和原型链

原型属性:每一个函数都有一个 原型属性:prototype
原型方法:每一个对象都有一个原型方法:proto
在构造函数中,通过prototype来定义函数中的方法
在构造函数中定义的属性和不是在构造函数中使用,而是在构造函数生成的实例化对象中使用
实例化对象中的proto指向的就是构造函数中prototype空间,指向其中定义的存储的函数
一个构造函数,也会有 proto 指向这个构造函数父级的 prototype空间
JavaScript中,所有的数据类型,都可以通过proto指向JavaScript的顶级对象,就是 Object对象

  • 原型链:就是通过 proto 这个属性,将JavaScript中的数据,相互串链起来,就称为 原型链

数组

数组中一些常用的方法

charAt() 获取指定位置上的字符
indexOf() 获取字符第一次出现的位置
substring() 截取字符串内容
slice() 截取
split() 将字符串分割成数组
replace() 替换
substr 返回一个从指定位置开始的指定长度的子字符串

ES6新增语法

1.、不一样的变量声明:const和let
2、模板字符串
3、箭头函数
4、函数的参数默认值
5、解构赋值

ES5中新增的数组的方法有哪些?

  • indexOf():返回第一次出现的下标
  • lastIndexOf():返回最后一次出现的下标
  • forEach() //遍历数组,无返回值,不改变原数组,仅仅只是遍历,常用于注册组件、指令等
    等。
  • map() //映射,遍历数组,返回一个新数组,不改变原数组
  • filter() ///过滤掉数组中不满足条件的值,返回一个新数组,不改变原数组
  • reduce() //累加器,reduce让数组的前后两项进行某种计算,然后返回其值,并继续计算,不改变原数组,返回计算的最终结果,从数组的第二项开始遍历。
  • every() //遍历数组每一项,每一项返回true,最终结果为true.有一项返回false,停止遍历,结果返回为false。不改变原数组。
  • some() //遍历数组每一项,有一项返回true,则停止遍历,结果返回true。不改变原数组。

ES6数组新方法

  • array.from():将类似数组的对象转化为数组
  • array.of():不管参数多少个,返回的都是由参数组成的数组
  • copywithin():赋值数组本身并改变数组元素,返回改变后的数组
  • find():找出第一个符合该函数参数条件的数组成员,参数是回调函数,返回该成员
  • findindex():返回该成员的索引
  • fill():给定值,覆盖数组的元素,参数:代替的值,开始位置,结束位置

ES6中对象新方法

  • Object.assign({},{}) :合并对象—–浅拷贝
  • Object.keys(对象):返回一个数组,数组存放所有key
  • Object.values(对象);返回一个数组,数组存放所有values
  • Object.entries(对象):返回一个数组,数组[key,values]
  • Object.is():比较两个值是否完全相等,与===基本一致
  • Object.getPrototypeOf():读取一个对象的原型对象
  • Object.setPrototypeOf():设置一个对象的prototype对象,返回参数对象本身

字符串

字符串常用方法

  • charAt():按照索引找到对应的字符,返回:字符
  • charCodeAt():按照索引找到对应的字符,返回值是字符编码
  • substring():按照索引位置截取字符,包前不包后,参数:开始索引,结束索引
  • substr():按照参数截取字符串,参数:开始索引,多少个
  • split():切割字符串,返回值是切割好的每一项
  • replace():把字符串里面某个数据给替换掉,只能替换一个,返回值:替换好的字符串
  • toLowerCase():把所有的大写字母替换成小写字母
  • toUpperCase():把所有的小写字母替换成大写字母
  • concat():拼接字符串
  • slice():和substring相似,不同的是参数可以为负

如何将数组转换为字符串?如何将字符串转换为数组

var str = 数组.join(’’)
var arr = 字符串.split(’’)
除此之外还有toString()

Math常见的API

1、Math.random() //随机数
2、Math.pow() //次方
3、Math.round() //四舍五入
4、Math.ceil() // 向上取整
5、Math.floor() //向下取整
6、Math.PI //π
7、Math.max() //返回最大值
8、Math.min() //返回最小值
9、Math.sqrt() //开方

正则表达式的方法

1、 test():匹配
作用:用来检测字符串是不是符合规则
返回值: 一个布尔值
2、 exec():捕获
作用: 用来把字符串里面符合要求的内容拿出来
语法: 正则.exec(你要捕获的字符串)
返回值: 一个数组
如果该字符串里面捕获不到内容,那么返回值就是一个 null
如果该字符串里面能捕获到内容
正则没有全局标识符 g 的时候,每次执行都是捕获到第一个能捕获的内容
正则由全局标识符 g 的时候,第二次执行是在上一次执行结束的位置开始捕获
如果正则里面有 ()
会在返回的数组里面单独把 () 里面的内容拿出来

call和apply的区别

1、call()
语法: 直接在函数名后面连接使用
参数1: 改变之后this的指向
参数2:从第二个参数开始: 依次是给函数传递参数的
2、 apply()
语法: 直接在函数名后面连接使用
参数1: 改变之后this的指向
参数2:数组或者伪数组都行,数组或者伪数组里面每一项依次是给函数传递参数

箭头函数

箭头函数没有this,this指向是外部作用域的this指向
箭头函数没有arguments
箭头函数不能作为构造函数,和 new 一起用会报错
箭头函数没有原型属性

闭包应用场景

1、函数防抖
2、使用闭包设计单例模式
3、为多个组件独立属性
4、设置私有变量

闭包优缺点

闭包的好处:

1.将一个变量长期保存内存中;
2.避免全局变量污染;
3私有成员的存在。

闭包的缺点:

1.常驻内存,增加内存使用量;
2.使用不当造成内存泄漏。

同源策略

同源策略导致跨域
同源策略:同一协议,同一 域名,同一端口号,当其中一条不满足时就会发生跨域
例如:localhost和127.0.0.1就会发生跨域
跨域
解决跨域的方法:
1、jsonp
利用 <script 标签没有跨域限制的漏洞。通过 script> 标签指向一个需要访问的地址并提供一个回调
函数来接收数据。
script标签里的src不会被同源策略所限制,src或者href链接的静态资源本质上就是一个get请求
原理:通过script标签,的src属性,定义跨域的访问的地址,在访问地址之后可以拼接参数,参数中定
义一个callback,后端执行callback,后端再把访问该src的数据拼接返回到该callback中,前端通过
callback获取数据
JSONP 使用简单且兼容性不错,但是只限于 get 请求。
2、CORS
CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。
浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现CORS,就实现了
跨域。
服务端设置 Access­Control­Allow­Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,
如果设置通配符则表示所有网站都可以访问资源。
3、document.domain
该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方式。
4、postMessage
这种方式通常用于获取嵌入页面中的第三方页面数据。一个页面发送消息,另一个页面判断来源并
接收消息
promise—es6新增的语法,是一个内置构造函数
语法: new Promise(function (resolve, reject) {})
返回值:一个叫做 promise对象
then(function () {}) 就是 resolve 调用的函数
catch(function () {}) 就是 reject 调用的函数

async/await 函数

语法:

  • async 是一个关键字
  • 写在函数的前面
  • 普通函数:async function fn() {}
  • 箭头函数:let fn = async () => {}
  • await 是一个关键字
  • 必须和async同时使用,如果没有async只写await会报错
    await 等待
  • 等待的必须是一个 promise 对象
  • await 关键字后面写的必须是一个 promise 对象
  • await 关键字有一个作用,就是可以把 promise 本该再 then 里面接受的结果
  • 直接再 await 前面定义一个变量来接受
  • let res1 = await pAjax({})
  • await 会把后面那个 promise 对象当作一个等待的对象
  • await 后面行的代码会等到这个 promise 执行完毕以后再继续

异步和同步的区别

同步是阻塞模式,异步是非阻塞模式。
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程
将会一直等待下去,知道收到返回信息才继续执行下去;
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回
式系统会通知进程进行处理,这样可以提高执行的效率。

状态码

200­请求成功
301­永久重定向
302­暂时重定向
304­缓存
404­客户端请求的语法错误,服务器无法理解
500­服务器端在执行时发生错误,无法完成请求

深拷贝和浅拷贝

只针对引用类型
1、浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
实现方法:Object.assign()
Array.prototype.concat()
Array.prototype.slice()
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
JSON.parse(JSON.stringify())

node的特点:

1,标准的异步编程
不会阻塞正常同步代码的执行
2,合理分配资源
让计算机,更加合理的执行程序
提高程序的执行效率,缩短执行事件
3,合理处理高 并发(所谓并发,就是同时执行)
同时处理多个需求(程序的执行,服务器的访问,数据的查询…)

PHP

加快网页运行速度的方法
使用CSS精灵减少HTTP请求
先加载CSS最后加载JavaScript

var,let,const的区别

1、变量提升
变量可以在声明之前使用
var有变量提升,let和const不发生变量提升
2、暂时性死区
在块级作用域中,let和const在声明变量之前使用会报错
3、重复声明
在相同作用域中let和const不允许重复声明
4、初始值
const 声明的是只读的常量,一旦声明,必须立即初始化,声明之后值不能改变。
5、作用域
ES5中没有块级作用域

变量的访问机制

当你在任何一个作用域里面访问一个变量的时候
如果自己作用域内部有这个变量,那么就直接使用
如果自己作用域内部没有这个变量,那么就去上一级作用域查找
如果还没有,就再去上一级作用域查找
一直到全局作用域都没有的话就会报错

变量的定义机制

声明一个变量
你在哪一个作用域里面定义的变量,这个变量就属于哪一个作用域
这个作用域的所有后代作用域可以访问,但是祖先级作用域不能访问

变量的赋值机制

当你给一个变量赋值的时候

  • 如果自己作用域内部有这个变量,那么就直接给自己的变量赋值
  • 如果自己没有,就给父级作用域的变量赋值
  • 如果父级作用域也没有,那么就给再父级的作用域里面的变量赋值
  • 一直到全局作用域都没有,那么就先把这个变量定义为全局变量,再进行赋值

三次握手

客户端和服务器建立连接 —–通过 TCP/IP 协议 , 来执行三次握手机制
第一次:客户端向服务器发送一个请求
客户端: 知道自己可以发送消息
服务器: 知道客户端可以发送消息
知道自己可以接收消息
第二次:服务器向客户端发送一个消息
服务器: 知道自己可以发送消息
客户端: 知道自己能接收消息
知道服务器可以接收消息
知道服务器可以发送消息
第三次:客户端向服务器发送请求
服务器: 知道客户端可以接收消息
确认双方都可以正常的发送接收消息之后,可以建立连接
每次请求之前,3次握手都需要执行

Guess you like

Origin blog.csdn.net/qq_45271323/article/details/106546499