0


前端热门面试题一

请解释一下什么是CSS的层叠和继承,并举例说明

CSS的层叠(Cascading)和继承(Inheritance)是CSS中两个重要的概念,它们共同定义了CSS样式如何应用于HTML文档中的元素。

CSS的层叠

CSS的层叠性指的是在同一元素上应用多个样式时,不同样式之间的优先级别以及如何进行组合和冲突解决的规则。具体来说,CSS采用“选择器优先级”规则来判断哪个样式优先级更高。当两个或多个样式规则冲突时,优先级高的规则将覆盖优先级低的规则。选择器的优先级可以通过以下方式计算(大致顺序,并非精确权重算法,但有助于理解):

  1. 内联样式(在HTML元素内部直接使用的style属性)的优先级最高。
  2. ID选择器(如#id)的优先级次之。
  3. 类选择器(如.class)、伪类选择器(如:hover)和属性选择器(如[type="text"])的优先级再次之。
  4. 元素选择器(如divp)和伪元素选择器(如::before::after)的优先级最低。

如果多个样式的优先级相同,则后面的样式会覆盖前面的样式。这种层叠性使得我们可以灵活地实现样式的复用和覆盖,同时也需要注意样式优先级的设置,避免产生冲突和意料之外的效果。

举例

/* 假设有以下CSS规则 */#uniqueDiv{color: red;}.textClass{color: blue;}/* HTML代码如下 */
<div id="uniqueDiv" class="textClass">这段文字的颜色是什么?</div>

在这个例子中,

#uniqueDiv

的优先级高于

.textClass

,因此文本的颜色将是红色。

CSS的继承

CSS的继承性指的是在父元素上定义的样式会被子元素继承,并且这些样式可以被子元素覆盖和修改。一些常见的CSS属性,如字体、颜色、文本对齐方式等,都具有继承性。这种特性可以减少CSS代码的冗余,增加代码的可维护性。但是,并非所有CSS属性都具有继承性,如布局和定位相关的属性通常不会被继承。

举例

/* 假设有以下CSS规则 */body{font-family: Arial, sans-serif;color: black;}/* 没有为h1特别设置字体或颜色 *//* HTML代码如下 */
<body>
    <h1>这是一个标题</h1>
    <p>这是一段文本。</p>
</body>

在这个例子中,

<h1>

<p>

标签都会继承

body

标签的

font-family

color

属性,除非它们自己或它们的父元素(在这个例子中没有)显式地覆盖了这些属性。因此,标题和文本都将使用Arial字体和黑色文字。

总结

CSS的层叠和继承是CSS中两个核心概念,它们共同决定了样式如何应用于HTML文档中的元素。层叠性允许我们解决样式冲突,而继承性则允许我们减少代码冗余并增加代码的可维护性。通过理解和运用这两个概念,我们可以更有效地编写CSS代码。

在JavaScript中,如何实现深拷贝和浅拷贝?并比较它们的区别

在JavaScript中,深拷贝和浅拷贝是处理对象时经常遇到的两种拷贝方式。它们的主要区别在于如何处理对象内部属性的拷贝。

浅拷贝(Shallow Copy)

浅拷贝仅复制对象的第一层属性,如果属性是基本类型(如字符串、数字等),则复制该属性的值。如果属性是引用类型(如对象、数组等),则复制的是对该属性引用的内存地址,因此原始对象和拷贝后的对象共享该引用类型的值。

实现浅拷贝的方法:
  1. 使用Object.assign()方法const original ={a:1,b:{c:2}};const copy = Object.assign({}, original);console.log(copy.b === original.b);// true,表示它们指向同一个对象
  2. 使用展开运算符(Spread Operator)const original ={a:1,b:{c:2}};const copy ={...original };console.log(copy.b === original.b);// true

深拷贝(Deep Copy)

深拷贝会递归地复制对象及其所有子属性,无论子属性是基本类型还是引用类型。因此,原始对象和拷贝后的对象将不会共享任何子属性,即它们在内存中是完全独立的。

实现深拷贝的方法:
  1. **使用JSON.parse()和JSON.stringify()**注意:这种方法不能处理函数、undefined、symbol等特殊类型的值,也不能正确处理循环引用的对象。const original ={a:1,b:{c:2}};const copy =JSON.parse(JSON.stringify(original));console.log(copy.b === original.b);// false
  2. 手动实现深拷贝函数为了处理所有情况(包括函数、循环引用等),你可能需要手动编写一个深拷贝函数。functiondeepClone(obj, hash =newWeakMap()){if(obj ===null)returnnull;// null 的情况if(obj instanceofDate)returnnewDate(obj);// 日期对象直接返回一个新的日期对象if(obj instanceofRegExp)returnnewRegExp(obj);// 正则对象直接返回一个新的正则对象// 如果循环引用了就用 weakMap 来解决if(hash.has(obj))return hash.get(obj);let allDesc = Object.getOwnPropertyDescriptors(obj);let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc); hash.set(obj, cloneObj);for(let key of Reflect.ownKeys(obj)){ cloneObj[key]=(typeof obj[key]==='object'&& obj[key]!==null)?deepClone(obj[key], hash): obj[key];}return cloneObj;}const original ={a:1,b:{c:2}};const copy =deepClone(original);console.log(copy.b === original.b);// false

区别

  • 浅拷贝:只复制对象的第一层属性,如果属性是引用类型,则只复制引用地址,因此原始对象和拷贝后的对象会共享该引用类型的值。
  • 深拷贝:递归地复制对象及其所有子属性,无论子属性是基本类型还是引用类型,都会复制一份新的,因此原始对象和拷贝后的对象在内存中是完全独立的。

选择哪种拷贝方式取决于你的具体需求,比如是否需要完全独立的对象副本,以及对象是否包含特殊类型(如函数、循环引用等)的值。


本文转载自: https://blog.csdn.net/hong161688/article/details/140286182
版权归原作者 hong161688 所有, 如有侵权,请联系我们删除。

“前端热门面试题一”的评论:

还没有评论