美团-前端开发面经(四)
点击上方蓝字关注我们
伪类和伪元素的区别
css引入伪类和伪元素概念是为了格式化文档树以外的信息。也就是说:伪类和伪元素是用来修饰不在文档树中的部分。比如,一句话中的第一个字母,或者是列表中的第一个元素。
伪类和伪元素的具体概念如下:
伪类:用于已有元素处于某种状态时为其添加对应的样式,这个状态是根据用户行为而动态变化的。【相关推荐:css在线手册】
例如:当用户悬停在指定元素时,可以通过:hover来描述这个元素的状态,虽然它和一般css相似,可以为已有元素添加样式,但是它只有处于DOM树无法描述的状态下才能为元素添加样式,所以称为伪类。
伪元素:用于创建一些不在DOM树中的元素,并为其添加样式。例如,我们可以通过:before来在一个元素之前添加一些文本,并为这些文本添加样式,虽然用户可以看见这些文本,但是它实际上并不在DOM文档中。
请看下面例子:
例一:
<ul>
<li>第一列</li>
<li>第二列</li></ul>
如果我们想要给第一列添加样式,我们可以通过以下两种方式:
(1)给第一列添加一个类,并在该类中定义样式:
<ul>
<li class="first-item">第一列</li>
<li>第二列</li></ul>.first-item{color:orange;}
(2)如果不用添加类的方法,我们可以通过给第一个<li>设置:first-child伪类来为其添加样式,这时,被修饰的li依然存在于DOM树中
<ul>
<li>第一个</li>
<li>第二个</li></ul>li:first-child{color:orage;}
例二:
<p>Hello World, and wish you have a good day!</p>
想要给该段落第一个字母添加样式,可以有以下方法:
(1)給第一个字母包裹<span>元素,并给span设置样式:
<p><span class="first">H</span>ello World, and wish you have a good day!</p>.first{color:red;}
(2)如果不创建<span>元素,我们可以通过给<p>元素设置P:first-letter伪元素为其添加样式,这时看起来像创建了一个虚拟的span元素并为其添加样式,但实际上在DOM数中并不存在这个span元素
<p>Hello World, and wish you have a good day!</p>p:first-letter{color:red;}
从上述例子中我们可以看出:伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档树外的元素。因此,伪类与伪元素的区别在于:有没有创建一个文档树之外的元素。
css3规范中要求使用双冒号(::)表示伪元素,以此来区分伪类和伪元素,比如::before和::after等伪元素使用双冒号(::),:hover和:active伪类使用单冒号(:)。除了一些低于IE8版本的浏览器外,大部分浏览器都支持伪元素的双冒号(::)表示方法。
然而除了少部分伪元素如::backdrop必须使用双冒号(::),大部分伪元素都支持单冒号和双冒号的写法,比如::after,写成:after一样可以正常运行。
w3c标准中说到,虽然CSS3标准要求伪元素使用双冒号的写法,但也依然支持单冒号的写法。为了向后兼容,我们建议你在目前还是使用单冒号的写法。
伪类侧重丰富选择器的选择语法范围内元素的选择能力,伪元素侧重表达或者定义不在语法定义范围内的抽象元素。
new操作符实现构造函数实例化的过程
以一个构造函数为例:
function Animal(v) { this.age=v };
let cat = new Animal(1);
(1) 创建一个空对象 {}
(2) 在该对象新增属性 __proto__ 指向 Foo.prototype
{
__proto__: Animal.prototype
}
(3) 执行构造函数时,将构造函数的 this 指向该对象。
{
__proto__: Animal.prototype
age: 1
}
(4) 构造函数没有 return,就返回该对象。
let cat = {
__proto__: Animal.prototype
age: 1
}
原型对象的数据结构
任何对象都存在 proto 属性,包括 prototype,正是通过 prototype.proto 指向其父类的原型对象,来实现了原型链。
Animal.prototype
{
__proto__: Object.prototype
constructor: Animal
}
Object.prototype
{
__proto__: null
constructor: Object
}
HTTP五层网络模型
物理层
物理层主要的作用就是定义物理设备如何去传输数据简单来说有没有物理我们的软件是没有办法去使用的所以呢物理层就是这些硬件设备相关的东西
数据链路层
数据链路层是在等我们的通信实体之间建立数据链路的连接。那么怎么理解呢?就是说,把我们的物理设备通过电路之类的链接到了一起。
网络层
网络层为数据在结点之间传输创建逻辑电路。比如访问一个百度的网址,发起请求后,会去寻找百度这个服务器的地址。它就是一个逻辑关系,它是在网络层为我们创建的
上面的第三层如果不是很了解也什么关系,因为这些会相对的底层,如果大家有兴趣的话可以自己去深入的了解,如果你没有什么兴趣你也不一定要非常了解才能做好个完美应用。
传输层
向用户提供端到端服务。我们的电脑和百度服务器建立连接之后,如何去传输数据,都是在这一层定义的。如果数据太大的话,分包,分片,传输,到了百度服务器之后,又需要重新的组装起来。传输层,向高层屏蔽了下层数据通信的细节。
应用层
为应用软件提供了很多服务。只要new一个服务对象,就可以使用相关的工具,传输数据,构建于TCP协议之上,屏蔽了网络传输的相关细节。
js中call,apply和bind方法的区别和使用场景
1、相同点:
三个函数都会改变this的指向(调用这三个函数的函数内部的this)
2、不同点:
1)、bind会产生新的函数,(把对象和函数绑定死后,产生新的函数)
2)、call和apply不会产生新的函数,只是在调用时,绑定一下而已。
3)、call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。
示例代码:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style type="text/css">
</style>
</head>
<body>
<!-- <input type="button" value="测试" onclick="testf()" /> -->
</body>
</html>
<script type="text/javascript">
//demo07面试题:请问bind,call,apply的区别
//1、相同点:
// 三个函数都会改变this的指向(调用这三个函数的函数内部的this)
//2、不同点:
// 1)、bind会产生新的函数,(把对象和函数绑定死后,产生新的函数)
// 2)、call和apply不会产生新的函数,只是在调用时,绑定一下而已。
// 3)、call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。
//示例代码:
var p1 = {
name:"隔壁老王",
}
function eat(str,drinkstr) {
console.log(this.name+"在吃"+str+",同时在喝"+drinkstr);
}
//1、bind:
let f1 = eat.bind(p1);//f1是个函数。即,用bind把eat函数和p1对象绑死,产生新的函数叫作f1
f1("油条","豆浆");//调用f1,就相当于 p1.eat();,内部的this就是p1,永远都是p1,不会是window
//2、call:
eat.call(p1,"油泼面","面汤");//不会产生新的函数,只是临时把eat函数和p1对象绑定一下。
//3、apply:(与call的意思一样,只是第二个参数是数组,是原函数eat的参数)
eat.apply(p1,["油泼面","面汤"]);//不会产生新的函数,只是临时把eat函数和p1对象绑定一下。
</script>
扫码二维码
获取更多面经
扶遥就业