深复制,BFC,DOM节点

前言

在知乎的某问题中有位同学去参加面试,一共遇到了以下的知识点:深复制以及你自己的实现方法,关于BFC的概念,关于遍历元素而非节点。。以及如何实现inserAfter。。好吧。我很water。。来总结一下查到的结果。。

深复制

深复制就是引用对象的复制问题。我们都知道,JS中引用类型和基本包装类型是不同的。对象,函数,数组,正则,日期~
我们在令a=某某,b=a;进行复制,又或者是通过原型来继承时,引用类型并没有进行完美的复制。
基本类型 a=1;b=a之后,a与b都有各自的内存,各自都为1;
但是引用类型就不是了,引用类型的名称只是指向堆内存的一个指针,堆内存中的值只能通过这个指针来访问,引用类型在复制时,实际上只复制了这个指针。但是堆内存中的内容是没有复制的。(这就导致了在构建对象时,数组作为对象的属性使用原型继承时会导致属性的共用)
那么怎么进行深复制呢?
最粗暴简单的做法是这样的:

JSON.parse(JSON.stringify(我们要复制的引用类型))

但是这种方法有一些缺点:
我们先把这个对象变成数组,再变成object后,它的构造函数就变成了object了。自己本身的constructor就丢失了。而且这个方法无法复制函数(函数怎么变成数组你说?)如果这个对象它内部有undefined,那么也无法复制。由于本身的构造函数丢失,那么正则,日期也是不能拷贝的。
那么怎么实现深复制呢?(个人认为这个题目有点难啊。。)
本water肯定暂时没这个能力的。。我们来看看github大神的作品:
https://github.com/cherryjs/cherry.js/blob/master/cherry.js
深复制要实现起来还是很麻烦的。。而且我目前根本没有遇到需要这种复制的情况出现。。。要两个对象一样的话,直接写两个一样的不就好了吗。。干嘛要复制。。(这个坑以后我是一定要填的)

BFC

这个其实我看明白以后就好解释了。
说白了以下的行为会创造出DFC,格式化的块级上下文:
根元素
display:为inline-block,table-cell,table-
caption,flex,inline-flex
float不为none
position不为abolute或fixed
overflow不为visible
而它的特质呢?
内部盒子垂直一个一个放置
垂直距离由margin决定,且会发生边距重叠
内部盒子会贴近父级的边缘
BFC区域不与浮动盒子重叠
BFC不影响外界
计算BFC高度时,浮动元素也参与
look!说白了就是个新的文档流嘛。
但是它有几个比较耐人寻味的特性:
BFC区域不与浮动盒子重叠
计算BFC高度时,浮动元素也参与
先说后者,一般的盒子在内部元素浮动后会塌陷,但是BFC却不是,它的高度能够与内部浮动元素适应
第二个不与浮动盒子重叠呢?
我们都知道把两个同级的盒子浮动后他们会横向排布,但是不会重叠,而BFC也是,它也会飘起来。
BFC会使得接下来浮动的元素换行。

节点类型

这个其实也简单,那个问题hi怎么遍历body里面div,ul标签内的全部内容,这里就会有一个概念了:
childNodes和children,一个返回的子节点,一个返回的子元素,一般来说子节点有很多种,元素,属性,注释,文本,而一般的HTML里面用childNodes的话的到的是元素和文本节点,去判断nodeType是为1(元素),3(文本)就可以了。如果要遍历子元素的话直接用children就可以了咯。注意,换行的话也是会产生文本节点的,所以具体情况具体分析。
然后就是insertAfter,直接分为在尾部appendChild,不在尾部,insertBefore到目标的nextSibling就好了!
再就是一个通用的方法:
element.insertAdjacentHTML(position, text);
第一个参数:
beforeBegin:在该元素前插入
afterBegin:在该元素第一个子元素前插入
beforeEnd:在该元素最后一个子元素后面插入
afterEnd:在该元素后插入
第二个参数:
插入的HTML代码

结语

哎,关于原生JS还是不熟,感觉自己盲点太多了。还需要多多学习。下一篇总结一下看到的几个面试题目吧。。其实都还挺基础的。。