前度面试总结,被问的概率极大

`·1.html5与css3的新特性

Html5:拖拽API,语义化标签(header,footer,side。。。)

​ 音频与视频API(audio,video),CanvaAPI,地理API, lo calStroage,sessionStroage,表单控件(date,time,email,url)

新技术webworker,websocket

Css3:边框属性(border),圆角(border-radius),阴影(box-shadow), 渐变,背景

CSS 单位中 px、em 和 rem 的区别

1、px 像素(Pixel)。绝对单位。像素 px 是相对于显示器屏幕分辨率而言的,是一 个虚拟长度单位,是计算机系统的数字化图像长度单位

2、em 是相对长度单位,相对于当前对象内文本的字体尺寸。如当前对行内文本的字 体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。它会继承父级元素的字体大 小,因此并不是一个固定的值

3、rem 是 CSS3 新增的一个相对单位(root em,根 em),使用 rem 为元素设定字 体大小时,仍然是相对大小,但相对的只是 HTML 根元素

4、区别: IE 无法调整那些使用 px 作为单位的字体大小,而 em 和 rem 可以缩放,rem 相对的只是 HTML 根元素。这个单位可谓集相对大小和绝对大小的优点于一身,通 过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐 层复合的连锁反应。目前,除了 IE8 及更早版本外,所有浏览器均已支持 rem

CSS 中 link 和@import 的区别

适用范围不同 @import 可以在网页页面中使用,也可以在 CSS 文件中使用,用来将多 个 CSS 文件引入到一个 CSS 文件中;而 link 只能将 CSS 文件引入到网页页面中

功能范围不同 link 属于 XHTML 标签,而@import 是 CSS 提供的一种方式,link 标签除 了可以加载 CSS 外,还可以定义 RSS,定义 rel 连接属性等,@import 就只能加载 CSS

加载顺序不同 当一个页面被加载的时候,link 引用的 CSS 会同时被加载,而@import 引用的 CSS 会等到页面全部被下载完再被加载。所以有时候浏览@import 加载 CSS 的页 面时开始会没有样式(就是闪烁),网速慢的时候还挺明显

兼容性 由于@import 是 css2.1 提出的,所以老的浏览器不支持,@import 只有在 IE5 以上的才能识别,而 link 标签无此问题

控制样式时的差别 使用 link 方式可以让用户切换 CSS 样式.现代浏览器如 Firefox,Opera,Safari 都支持 rel=”alternate stylesheet”属性(即可在浏览器上选择不同 的风格), 当然你还可以使用 Javascript 使得 IE 也支持用户更换样式

权重区别 link 引入的样式权重大于@import 引入的样式

BFC 是什么

为"块级格式化上下文"。它是一个独立的渲染区域;并且与这个区 域外部毫不相干

布局规则

1、内部的 Box 会在垂直方向,一个接一个地放置

2、Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠

3、每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往 右的格式化,否则相反)。即使存在浮动也是如此 4、BFC 的区域不会与 float box 重叠

5、BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反 之也如此

6、计算 BFC 的高度时,浮动元素也参与计算

哪些元素会生成 BFC: 1、根元素 2、float 属性不为 none 3、position 为 absolute 或 fixed 4、display 为 inline-block, table-cell, table-caption, flex, inline-flex 5、overflow 不为 visible

超出显示省略号:

​ 1.单行:overflow:hidden;white-space:nowrap;

​ text-overflow:hidden

​ 2.多行:display:-webkit-box-;-webkit-box-orient:vertical;

​ -webkit-line-clamp:3;overflow:hidden

http1.0和2.0

2.**Http1.0:**无状态的,无连接的

Http1.1:持久化,请求管道化,增加缓存处理(新的字段如cache-control)

​ 增加Host字段,支持断点传输

Http2.0:二进制分帧,多路复用,头部压缩,服务器推送

多路复用:

1、所有的HTTP2.0通信都在一个TCP连接上完成,这个连接可以承载 任意数量的双向数据流。

2、每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id)重新组装。

Http与Https的区别

​ 1. 安全性上,HTTPS是安全超文本协议,在HTTP基础上有更强的安全性。简单来说,HTTPS是使用TLS/SSL加密的HTTP协议

​ 2. 申请证书上,HTTPS需要使用ca申请证书

​ 3. 传输协议上, HTTP是超文本传输协议,明文传输;HTTPS是具有安全性的 SSL 加密传输协议

  4. 连接方式与端口上,http的连接简单,是无状态的,端口是 80; https 在http的基础上使用了ssl协议进行加密传输,端口是 443
常见http状态码

200( OK):请求已成功,请求所希望的响应头或数据体将随此响应返回。

303( See Other):告知客户端使用另一个 URL 来获取资源。

400( Bad Request):请求格式错误。1)语义有误,当前请求无法被服务器理解。除非进行 修改,否则客户端不应该重复提交这个请求;2)请求参数有误。

404( Not Found):请求失败,请求所希望得到的资源未被在服务器上发现。 500( Internal Server Error):服务器遇到了一个未曾预料的状况,导致了它无法完成对请 求的处理

Ajax的实现流程

1、创建 XMLHTTPRequest 对象,也就是创建一个异步调用对象.

2、创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、URL 及验证信息.

3、设置响应 HTTP 请求状态变化的函数.

4、发送 HTTP 请求.

5、获取异步调用返回的数据.

6、使用 JavaScript 和 DOM 实现局部刷新.

Get 和 Post 的区别?

1、GET 使用 URL 或 Cookie 传参。而 POST 将数据放在 BODY 中

2、GET 的 URL 会有长度上的限制,则 POST 的数据则可以非常大

3、POST 比 GET 安全,因为数据在地址栏上不可见

最本质的区别 Get 是用来从服务器上获得数据,而 post 是用来向服务器上传递数据 Get/Post 使用场景

若符合下列任一情况,则 post 方法:

1、请求的结果有持续性的作用,例如:数据库内添加新的数据行

2、若使用 get 方法,则表单上收集的数据可能让 URL 过长

3、要传送的数据不是采用 ASCII 编码

若符合下列任一情况,则用 Get 方法:

1、请求是为了查找资源,html 表单数据仅用来搜索

2、请求结果无持续性的副作用

3、收集的数据及 html 表单内的输入字段名称的总长不超过 1024 个字符

Tcp的三次握手:
1、第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
2、第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器 进入SYN_RECV状态;
3、第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED状态,完成三次握手
Tcp的四次挥手:

(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

TCP与UDP的区别:
UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
连接对象个数支持一对一,一对多,多对一和多对多交互通信只能是一对一通信
传输方式面向报文面向字节流
首部开销首部开销小,仅8字节首部最小20字节,最大60字节
适用场景适用于实时应用(IP电话、视频会议、直播等)适用于要求可靠传输的应用,例如文件传输
原型

原型:JS声明构造函数(用来实例化对象的函数)时,会在内存中创建一个对应的对象,这个对象就是原函数的原型。构造函数默认有一个prototype属性,prototype的值指向函数的原型。同时原型中也有一个constructor属性,constructor的值指向函数对象。
通过构造函数实例化出来的对象,并不具有prototype属性,其默认有一个__proto__属性,__proto__的值指向构造函数的原型。在原型对象上添加或修改的属性,在所有实例化出的对象上都可共享。

1.每个函数function都有一个prototype,即显示原型(属性)

2.每个通过函数实例出来的对象都有一个__proto__,可称为隐私原型(属性)

3.对象的隐式原型的值为其对应构造函数的显示原型的值

识别数组的方法

is.Array instanceof Object.prototype.toString.call

原型链

当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构

原型的作用:

1.数据共享 节约内存内存空间
2.实现继承

hasOwnProperty 函数检测对象自身是否含有某个属性

getOwnPropertyNames 函数可以获取对象所有的自身属性

闭包

“闭包就是能够读取其他函数内部变量的函数。例如在 javascript 中,只有函数内部的子函数 才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函 数内部和函数外部连接起来的桥梁。”

Vue中的data为什么是函数

在这里插入图片描述

MVVC和MVC模型

在这里插入图片描述

OSI七层模型

在这里插入图片描述

单页和多页的区别

在这里插入图片描述

强缓存

即直接从本地读取缓存副本,不需要发起请求

两个字段控制: Expires 和 Cache-Control

Expires 是以前用来控制缓存的http头,Cache-Control是新版的API。 现在首选Cache-Control。 如果在Cache-Control响应头设置了"max-age" 或者"s-max-age" 指令,那么Expires 头会被忽略

协商缓存

当本地缓存过期的时候,浏览器会尝试协商缓存,协商缓存会发起请求,已验证本地副本是否可以使用

两个字段控制:Last-Modified 和 ETag

Last-Modified 和 ETag 的区别:一个是具体的修改时间 一个是一个状态码,通过该状态码访问服务器是否是最近资源 如果是就返回304

js为什么会是单线程

js是作为浏览器的脚本语言,主要是实现用户与浏览器的交互,以及操作dom;这决定了它只能是单线程,否则会带来很复杂的同步问题。 举个例子:如果js被设计了多线程,如果有一个线程要修改一个dom元素,另一个线程要删除这个dom元素,此时浏览器就会一脸茫然,不知所措。所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变

进程与线程

进程是cpu分配资源的最小单位;(是能拥有资源和独立运行的最小单位)

线程是cpu调度的最小单位;(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)

typeof和instanceof

这两个方法都可以用来判断变量类型
区别:前者是判断这个变量是什么类型,后者是判断这个变量是不是某种类型,返回的是布尔值

typeof返回一个数据类型的字符串,而且都是小写的字符串,返回值

typeof的缺陷:1.不能判断变量具体的数据类型比如数组、正则、日期、对象,因为都会返回object,不过可以判断function

2.判断null的时候返回的是一个object,这是js的一个缺陷,判断NaN的时候返回是number

instanceof:可以用来检测这个变量是否为某种类型,返回的是布尔值,并且可以判断这个变量是否为某个函数的实例,它检测的是对象的原型

js的事件模型

事件冒泡,事件处理,事件捕获

双向绑定原理

核心是采用数据劫持结合发布者订阅者模式,通过Object.defineProperty()对每个属性的get和set进行拦截。在数据发生变化的时候发布消息给订阅者,触发相应的监听回调。

1、需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter, 这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化

2、compile 解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每 个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视 图

3、Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做的事情是:

​ 3.1)在自身实例化时往属性订阅器(dep)里面添加自己

​ 3.2)自身必须有一个 update()方法

​ 3.3)待属性变动 dep.notice()通知时,能调用自身的 update()方法,并触发 Compile 中 绑定的回调,则功成身退。

4、MVVM 作为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,通 Observer 来监 听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据 model 变更的双向绑定效果

Vue组件间的传值

1、父组件向子组件传递数据 父组件内设置要传的数据,在父组件中引用的子组件上绑定一个自定义属性并把数据 绑定在自定义属性上,在子组件添加参数 props 接收即可

2、子组件向父组件传递数据 子组件通过 vue 实例方法$emit 进行触发并且可以携带参数,父组件监听使用@(v-on) 进行监听,然后进行方法处理

3、非父子组件之间传递数据

3.1 引入第三方 new vue 定义为 eventBus

3.2)在组件中 created 中订阅方法 eventBus.$on(“自定义事件名”,methods 中的方法名)

3.3) 在另一个兄弟组件中的 methods 中写函数,在函数中发布 eventBus 订阅的方法 eventBus.$emit("自定义事件名”)

3.4) 在组件的 template 中绑定事件(比如 click)

为什么避免 v-if 和 v-for 用在一起

当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过 v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运 算 v-for

watch、methods 和 computed 的区别

​ methods是通过事件驱动来执行函数的,是被动的

  1. Computed是计算属性,类似于过滤器,对绑定到视图的数据进行处理,并监听变化进而执行对应的方法。计算属性是基于他们的依赖进行缓存的。只有在相关依赖发生改变时,它们才会重新求值。
  2. Watch是一个侦听的动作,用来观察和响应Vue实例上的数据变动
  3. 异同:它们都是vue对监听器的实现,只不过computed主要用于对同步数据的处理watch则主要用于观测某个值的变化去完成一段开销较大的复杂业务逻辑。能用computed的时候先用computed,避免了多个数据影响其中某个数据时多次调用watch的情况。
  4. 运用场景:当我们需要进行数值计算时,并且依赖于其他数据时,应该使用computed;当我们需要在数据变化时执行异步或者开销较大的操作时,应该使用watch
r o u t e 和 route 和 routerouter 的区别是什么?

$route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由 信息参数

r o u t e r 为 V u e R o u t e r 的 实 例 , 相 当 于 一 个 全 局 的 路 由 器 对 象 , 里 面 含 有 很 多 属 性 和 子 对 象 , 例 如 h i s t o r y 对 象 , 经 常 用 的 跳 转 链 接 就 可 以 用 t h i s . r o u t e r . p u s h 会 往 h i s t o r y 栈 中 添 加 一 个 新 的 记 录 。 返 回 上 一 个 h i s t o r y 也 是 使 用 router 为 VueRouter 的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象, 例如 history 对象,经常用的跳转链接就可以用 this.router.push 会往 history 栈中添加一个新的记 录。返回上一个 history 也是使用 routerVueRouterhistorythis.router.pushhistoryhistory使router.go 方法

怎样理解 Vue 的单向数据流?

1、数据从父级组件传递给子组件,只能单向绑定

2、子组件内部不能直接修改从父级传递过来的数据

3、所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向 下流动到子组件中,但是反过来则不行,这样会防止从子组件意外改变父级组件的状态,从而导 致你的应用的数据流向难以理解。

4、每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值,这意味着你 不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告

5、子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修 改

箭头函数和普通函数的区别

用了箭头函数,this 就不是指向 window,而是父级(指向是可变的)

不能够使用 arguments 对象

不能用作构造函数,这就是说不能够使用 new 命令,否则会抛出一个错误

不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数

promise的三个状态

等待(pending)~已完成(fulilled)~已拒绝(rejected)

promise与async的区别
  1. 执行async函数返回的都是Promise对象
  2. Promise.then成功的情况下对应await
  3. Promise.catch异常的情况对应 async中的try catch
  4. async/await更符合同步语义,容易理解,使得异步代码更像是同步代
  5. async/await是基于promise实现的
  6. async/await是生成器函数的语法糖,拥有内置执行器,不需要额外的调用,直接会自动调用并返回一个promise对象
promise

Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果

Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法

then 链式操作的用法

从表面上看,Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多

p.then((data) => {
    console.log(data);
})
.then((data) => {
    console.log(data);
})
.then((data) => {
    console.log(data);
});
reject的用法 :

把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调

    let p = new Promise((resolve, reject) => {
        //做一些异步操作
      setTimeout(function(){
            var num = Math.ceil(Math.random()*10); //生成1-10的随机数
            if(num<=5){
                resolve(num);
            }
            else{
                reject('数字太大了');
            }
      }, 2000);
    });
    p.then((data) => {
            console.log('resolved',data);
        },(err) => {
            console.log('rejected',err);
        }
    ); 

then中传了两个参数,then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调

catch的用法

它和then的第二个参数一样,用来指定reject的回调

p.then((data) => {
    console.log('resolved',data);
}).catch((err) => {
    console.log('rejected',err);
})
all的用法:

谁跑的慢,以谁为准执行回调。all接收一个数组参数,里面的值最终都算返回Promise对象

let Promise1 = new Promise(function(resolve, reject){})
let Promise2 = new Promise(function(resolve, reject){})
let Promise3 = new Promise(function(resolve, reject){})
 
let p = Promise.all([Promise1, Promise2, Promise3])
 
p.then(funciton(){
  // 三个都成功则成功  
}, function(){
  // 只要有失败,则失败 
})
race的用法

谁跑的快,以谁为准执行回调

nextTick

**官方说明:**在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

原理:
this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上

Vue 是异步修改 DOM 的并且不鼓励开发者直接接触 DOM,但有时候业务需要必须对 数据更改–刷新后的 DOM 做相应的处理,这时候就可以使用 Vue.nextTick(callback)这个 api 了

ES6

let,const 解构赋值 模板字符串 简化对象写法 箭头函数 (…)扩展运算符 symbol promise

flex是由flex-grow,flex-shrink,flex-bas的缩写
数组的方法

join() 数组变成字符串

spilt() 字符串变数组

push() 可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度

pop() 数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项

shift() 删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined

unshift() 将参数添加到原数组开头,并返回数组的长度

sort() 按升序排列数组项——即最小的值位于最前面,最大的值排在最后面

reverse() 反转数组项的顺序

concat() 将参数添加到原数组中。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本

slice() 返回从原数组中指定开始下标到结束下标之间的项组成的新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项

splice() 很强大的数组方法,它有很多种用法,可以实现删除、插入和替换

indexOf() 接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找

lastIndexOf 接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找

forEach() 对数组的每一项运行给定函数,该方法没有返回值

some(): 对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true

every() 对数组中的每一项运行都给定函数,如果该函数对每一项都返回true,则返回true

filter() :对数组的每一项运行给定函数,返回该函数会返回true的项组成的数组

map() :对数组的每一项运行给定函数,返回每次函数调用结果所组成的数组

import与require的区别
加载方式规范命令特点
运行时加载CommonJS/AMDrequire提供了服务器/浏览器的模块加载方案。非语言层面的标准。只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化。
编译时加载ES6+import语言规格层面支持模块功能。支持编译时静态分析,便于JS引入宏和类型检验。动态绑定
Vue 项目优化的解决方案都有哪些

1、 使用 mini-css-extract-plugin 插件抽离 css

2、 配置 optimization 把公共的 js 代码抽离出来

3、 通过 webpack 处理文件压缩

4、 不打包框架、库文件,通过 cdn 的方式引入

5、 小图片使用 base64

6、 配置项目文件懒加载

7、 UI 库配置按需加载

8、 开启 Gzip 压缩

SPA单页面的优缺点

1、 优点:

1,1)无刷新界面,给用户体验原生的应用感觉

1,2)节省原生(android 和 ios)app 开发成本

1,3)提高发布效率,无需每次安装更新包

1,4)容易借助其他知名平台更有利于营销和推

1,5)符合 web2.0 的趋势

2、 缺点:

1) 效果和性能确实和原生的有较大差距

2) 各个浏览器的版本兼容性不一样

3) 业务随着代码量增加而增加,不利于首屏优化

4) 某些平台对 hash 有偏见,有些甚至不支持 pushstate

5) 不利于搜索引擎抓取

Vue 首屏加载实现优化

1、把不常改变的库放到 index.html 中,通过 cdn 引入

2、vue 路由的懒加载

3、不生成 map 文件

4、vue 组件尽量不要全局引入

5、使用更轻量级的工具库

6、开启 gzip 压缩

7、首页单独做服务端渲染

new操作符都干了什么

(1)创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
(2)设置原型链 空对象指向构造函数的原型对象。
(3)执行函数体 修改构造函数 this 指针指向空对象,并执行函数体。

(4)判断返回值 返回对象就用该对象,没有的话就创建一个对象

浅拷贝与深拷贝

基本数据类型 --名值存储在栈内存中,复制时会开辟一个新的内存

引用数据类型–名存在栈内存中,值存在堆内存中,但是复制时栈内存会提供一个引用的地址指向堆内存中的值

let obj = {name:{name:'1',id:[2,[3,4]]},id:[[1,2],[3,4]],son:undefined,sister:Symbol(1),fun:function(){return 1}}
const deepClone = (obj)=>{
    let res = typeof obj==='obejct'?{}:[];
    if(obj&&typeof obj ==='object'){
        for(let key in obj){
            if(obj[key]&& typeof obj[key]==='object'){
                res[key] = deepClone(obj[key])
            }else{
                res[key] = obj[key];
            }
        }
    }
    return res;
}
let obj2 = deepClone(obj);
obj.name.name='2';
obj.id[0][0]=10;
console.log(obj2);  
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值