2021前端经典面试题

文章目录

一、HTML

1、Label 的作用是什么?是怎么用的?

答案:label 标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上

两种用法:一种是 id 绑定,一种是嵌套

2.iframe 框架有那些优缺点?

优点:

  • iframe 能够原封不动的把嵌入的网页展现出来。

  • 如果有多个网页引用 iframe,那么你只需要修改 iframe 的内容,就可以实现调用的每一个页面内容的更改,方便快捷。

  • 网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用 iframe 来嵌套,可以增加代码的可重用。

  • 如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由 iframe 来解决。

缺点:

  • 框架结构中出现各种滚动条

  • iframe 会阻塞主页面的 Onload 事件

  • 搜索引擎的检索程序无法解读这种页面,不利于 SEO

  • iframe 和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。

3、HTML 与 XHTML 二者有什么区别,你觉得应该使用哪一个并说出理由。

应该使用XHTML,因为XHTML是XML重写了HTML的规范,比HTML更加严格,表现如下:

  • 1、XHTML中所有的标记都必须有一个相应的结束标签;

  • 2、XHTML所有标签的元素和属性的名字都必须使用小写;

  • 3、所有的XML标记都必须合理嵌套;

  • 4、所有的属性都必须用引号“”括起来;

  • 5、把所有<和&特殊符号用编码表示;

  • 6、给所有属性附一个值;

  • 7、不要在注释内容中使用“–”;

  • 8、图片必须使用说明文字。

4、title 与 h1 的区别、b 与 strong 的区别、i 与 em 的区别?

①title用于网站信息标题,突出网站标题或关键字,一个网站可以有多个title,seo权重高于H1;H1概括的是文章主题,一个页面最好只用一个H1,seo权重低于title。

解析:

  • A.从网站角度而言,title则重于网站信息标题,突出网站标题或关键字用title,一篇文章,一个页面最好只

  • 用一个H1,H1用得太多,会稀释主题;一个网站可以有多个title,最好一个单页用一个title以便突出网站页面主题信息。

  • B.从文章角度而言,H1则概括的是文章主题,突出文章主题,用H1,面对的用户,要突出其视觉效果。

  • C.从SEO角度而言,title的权重高于H1,其适用性要比H1广。

②b为了加粗而加粗,strong为了标明重点而加粗

解析:

  • A.b这个标签对应 bold,即文本加粗,其目的仅仅是为了加粗显示文本,是一种样式/风格需求;

  • B.strong这个标签意思是加强字符的语气,表示该文本比较重要,提醒读者/终端注意。为了达到这个目的,浏览器等终端将其加粗显示;

③ 同②i为了斜体而斜体,em为了标明重点而斜体,且对于搜索引擎来说strong和em比b和i要重视的多

5、请描述下 SEO 中的 TDK?

在 SEO(搜索引擎最佳化Search Engine Optimization) 中,所谓的 TDK 其实就是 title、description、keywords 这三个标签,title 标题标签,description 描述标签,keywords 关键词标签。

6、每个 HTML 文件头里都有个很重要的东西,Doctype,知道这是干什么的么?

<!DOCTYPE> 声明位于文档中的最前面的位置,处于 <html> 标签之前。

1.告知浏览器文档使用哪种 HTML 或 XHTML 规范。

2.告诉浏览器按照何种规范解析页面(如果你的页面没有 DOCTYPE 的声明,那么 compatMode 默认就是 BackCompat,浏览器按照自己的方式解析渲染页面)

7、简述一下 src 与 href 的区别。

​ src 用于引用资源,替换当前元素;href 用于在当前文档和引用资源之间确立联系。

解析:

  • href
    href 标识超文本引用,用在 link 和 a 等元素上,href 是引用和页面关联,是在当前元素和引用资源之间建立联系

    若在文档中添加 href ,浏览器会识别该文档为 CSS 文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用 link 方式加载 CSS,而不是使用 @import 方式。
  • src
    src 表示引用资源,替换当前元素,用在 img,script,iframe 上,src 是页面内容不可缺少的一部分。

    当浏览器解析到 src ,会暂停其他资源的下载和处理(图片不会暂停其他资源下载和处理),直到将该资源加载、编译、执行完毕,图片和框架等也如此,类似于将所指向资源应用到当前内容。这也是为什么建议把 js 脚本放在底部而不是头部的原因。
8、对于 WEB 标准以及 W3C 的理解与认识问题

web 标准简单来说可以分为结构、表现和行为。其中结构主要是有 HTML 标签组成。或许通俗点说,在页面 body 里面我们写入的标签都是为了页面的结构。表现即指 css 样式表,通过 css 可以是页面的结构标签更具美感。行为是指页面和用户具有一定的交互,同时页面结构或者表现发生变化,主要是有 js 组成。

web 标准一般是将该三部分独立分开,使其更具有模块化。但一般产生行为时,就会有结构或者表现的变化,也使这三者的界限并不那么清晰。

W3C 对 web 标准提出了规范化的要求,也就是在实际编程中的一些代码规范:包含如下几点:

1.对于结构要求:(标签规范可以提高搜索引擎对页面的抓取效率,对 SEO 很有帮助)

1)标签字母要小写

2)标签要闭合

3)标签不允许随意嵌套

2.对于 css 和 js 来说

1)尽量使用外链 css 样式表和 js 脚本。是结构、表现和行为分为三块,符合规范。同时提高页面渲染速度,提高用户的体验。

2)样式尽量少用行间样式表,使结构与表现分离,标签的 id 和 class 等属性命名要做到见文知义,标签越少,加载越快,用户体验提高,代码维护简单,便于改版

3)不需要变动页面内容,便可提供打印版本而不需要复制内容,提高网站易用性。

9、前端页面有哪三层构成,分别是什么?作用是什么?

1、结构层(structural layer)

​ 由 HTML 或 XHTML 之类的标记语言负责创建。标签,也就是那些出现在尖括号里的单词,对网页内容的语义含义做出了描述,但这些标签不包含任何关于如何显示有关内容的信息。例如,P 标签表达了这样一种语义:“这是一个文本段。”

2、表示层(presentation layer)

​ 由 CSS 负责创建。 CSS 对“如何显示有关内容”的问题做出了回答。

3、行为层(behaviorlayer)

​ 负责回答“内容应该如何对事件做出反应”这一问题。这是 Javascript 语言和 DOM 主宰的领域。

10、div+css 的布局较 table 布局有什么优点?

答案:分离 方便改版 快 清晰简洁 seo

1.改版的时候更方便 只要改 css 文件。

2.页面加载速度更快、结构化清晰、页面显示简洁。

3.表现与结构相分离。

4.易于优化(seo)搜索引擎更友好,排名更容易靠前。

11、html 常见兼容性问题?

1、png24位的图片在iE6浏览器上出现背景
​ 解决方案:做成PNG8,也可以引用一段脚本处理.

2、浏览器默认的margin和padding不同
​ 解决方案:加一个全局的 *{margin:0;padding:0;} 来统一。

3、IE6双边距bug:在IE6下,如果对元素设置了浮动,同时又设置了margin-left或margin-right,margin值会加倍。

box{ float:left; width:10px; margin:0 0 0 10px;}

​ 这种情况之下IE会产生20px的距离
​ 解决方案:在float的标签样式控制中加入 _display:inline; 将其转化为行内属性。( _ 这个符号只有ie6会识别)

4、渐进识别的方式,从总体中逐渐排除局部。
​ 首先,巧妙的使用“\9”这一标记,将IE游览器从所有情况中分离出来。
接着,再次使用 “+” 将IE8和IE7、IE6分离开来,这样IE8已经独立识别。
复制代码

.bb{
background-color:#f1ee18; /所有识别/
.background-color:#00deff\9; /IE6、7、8识别/
+background-color:#a200ff; /IE6、7识别/
_background-color:#1e0bd1; /IE6识别/
}

5、IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute() 获取自定义属性;Firefox下,只能使用getAttribute()获取自定义属性
​ 解决方法:统一通过getAttribute()获取自定义属性

6、IE下,event对象有 x、y 属性,但是没有 pageX、pageY属性; Firefox下,event对象有 pageX、pageY 属性,但是没有 x、y 属性
​ 解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。

7、Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示
​ 解决方法:可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决

8、超链接访问过后 hover 样式就不出现了,被点击访问过的超链接样式不在具有 hover 和 active 了
​ 解决方法:改变CSS属性的排列顺序 L-V-H-A

a:link {}
a:visited {}
a:hover {}
a:active {}

9、怪异模式问题:漏写 DTD 声明,Firefox 仍然会按照标准模式来解析网页,但在 IE 中会触发怪异模式。为避免怪异模式给我们带来不必要的麻烦,最好养成书写 DTD 声明的好习惯。现在可以使用html5 推荐的写法

10、上下margin重合问题:ie和ff都存在,相邻的两个div的margin-left和margin-right不会重合,但是margin-top和margin-bottom却会发生重合。

​ 解决方法:养成良好的代码编写习惯,同时采用margin-top或者同时采用margin-bottom。

11、ie6对png图片格式支持不好
​ 解决方案:引用一段脚本处理

12、html5 有哪些新特性、移除了那些元素?

新特性:

1、离线缓存。可以在关闭浏览器后再次打开时恢复数据,以减少网络流量。
2、音频视频自由嵌入,多媒体形式更灵活。
3、地理位置定位。
4、canvas绘图,提升移动平台的绘图能力。
5、提升交互能力,拖拽、撤销历史操作、文本选择等。
6、开发及维护成本低。
7、css3视觉设计师的辅助利器的支持。
8、可以调用手机摄像头、手机相册和通讯录等功能。

移除的元素:

  1. 纯表现的元素:basefont,big,center,font, s,strike,tt,u;
  2. 对可用性产生负面影响的元素:frame,frameset,noframes;
13、HTML5 的离线储存怎么使用,工作原理能不能解释一下?

​ 在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。

原理:HTML5 的离线存储是基于一个新建的.appcache 文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像 cookie 一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。

使用方法:

只要在头部加一个 manifest 属性就 ok 了

<!DOCTYPE html>
<html manifest="cache.manifest">
  ...
</html>

然后 cache.manifest 文件的书写方式如下:

CACHE MANIFEST
#v0.11

CACHE:

js/app.js
css/style.css

NETWORK:
resourse/logo.png

FALLBACK:
/ /offline.html
14、HTML 全局属性(global attribute)有哪些
  • class:为元素设置类标识
  • data-*: 为元素增加自定义属性
  • draggable: 设置元素是否可拖拽
  • id: 元素id,文档内唯一
  • lang: 元素内容的的语言
  • style: 行内css样式
  • title: 元素相关的建议信息
15、meta viewport 原理是什么?

​ meta viewport 标签的作用是让当前 viewport 的宽度等于设备的宽度,同时不允许用户进行手动缩放

​ viewport的原理:移动端浏览器通常都会在一个比移动端屏幕更宽的虚拟窗口中渲染页面,这个虚拟窗口就是 viewport; 目的是正常展示没有做移动端适配的网页,让他们完整的展示给用户;

16、DOM 和 BOM 有什么区别

DOM:

Document Object Model,文档对象模型

DOM 是为了操作文档出现的 API,document 是其的一个对象

DOM 和文档有关,这里的文档指的是网页,也就是 html 文档。DOM 和浏览器无关,他关注的是网页本身的内容。

BOM:

Browser Object Model,浏览器对象模型

BOM 是为了操作浏览器出现的 API,window 是其的一个对象

window 对象既为 javascript 访问浏览器提供 API,同时在 ECMAScript 中充当 Global 对象

17、img 上 title 与 alt

答案:title 指图片的信息、alt 指图片不显示时显示的文字

二、CSS

1、标准的 CSS 的盒子模型?低版本 IE 的盒子模型有什么不同?

(1)有两种, IE 盒子模型、W3C 盒子模型;

(2)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border);

(3)区 别: IE 的 content 部分把 border 和 padding 计算了进去;

2、CSS 隐藏元素的几种方法(至少说出三种)
  • Opacity : 0 元素本身依然占据它自己的位置并对网页的布局起作用。它也将响应用户交互;
  • Visibility:hidden 与 opacity 唯一不同的是它不会响应任何用户交互。此外,元素在读屏软件中也会被隐藏;
  • Display:display 设为 none 任何对该元素直接打用户交互操作都不可能生效。此外,读屏软件也不会读到元素的内容。这种方式产生的效果就像元素完全不存在;
  • Position: 不会影响布局,能让元素保持可以操作;
  • Clip-path:clip-path 属性还没有在 IE 或者 Edge 下被完全支持。如果要在你的 clip-path 中使用外部的 SVG 文件,浏览器支持度还要低;
3、CSS 清除浮动的几种方法(至少两种)

清除浮动: 核心:clear:both;

1.使用额外标签法(不推荐使用)

​ 在浮动的盒子下面再放一个标签,使用 clear:both;来清除浮动

​ a 内部标签:会将父盒子的高度重新撑开

​ b 外部标签:只能将浮动盒子的影响清除,但是不会撑开盒子

2.使用 overflow 清除浮动(不推荐使用)

​ 先找到浮动盒子的父元素,给父元素添加一个属性:overflow:hidden;就会清除子元素对页面的影响

3.使用伪元素清除浮动(用的最多)

​ 伪元素:在页面上不存在的元素,但是可以通过 css 添加上去

种类:
:after(在。。。之后)
:before(在。。。之前)

注意:每个元素都有自己的伪元素

.clearfix:after {
    content:"";
    height:0;
    line-height:0;
    display:block;
    clear:both;
    visibility:hidden;  /_将元素隐藏起来_/ 
      在页面的 clearfix 元素后面添加了一个空的块级元素
     (这个元素的高为 0 行高也为 0   并且这个元素清除了浮动)
}
.clearfix {
  zoom:1;/_为了兼容 IE6_/
}
4、页面导入样式时,使用 link 和@import 有什么区别?

1. Link 属于 html 标签,而@import 是 CSS 中提供的

2. 在页面加载的时候,link 会同时被加载,而@import 引用的 CSS 会在页面加载完成后才会加载引用的 CSS

3. @import 只有在 ie5 以上才可以被识别,而 link 是 html 标签,不存在浏览器兼容性问题

4. Link 引入样式的权重大于@import 的引用(@import 是将引用的样式导入到当前的页面中)

5、伪元素和伪类的区别?

1、伪元素使用 2 个冒号,常见的有:::before,::after,::first-line,::first-letter,::selection、::placeholder 等;

​ 伪类使用1个冒号,常见有::hover,:link,:active,:target,:not(),:focus等。

2、伪元素添加了一个页面中没有的元素(只是从视觉效果上添加了,不是在文档树中添加);

​ 伪类是给页面中已经存在的元素添加一个类。

6、 CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3 新增伪类有那些?
  • 1.id选择器( # myid)

  • 2.类选择器(.myclassname)

  • 3.标签选择器(div, h1, p)

  • 4.相邻选择器(h1 + p)

  • 5.子选择器(ul < li)

  • 6.后代选择器(li a)

  • 7.通配符选择器( * )

  • 8.属性选择器(a[rel = “external”])

  • 9.伪类选择器(a: hover, li: nth - child)

*   可继承: font-size font-family color, UL LI DL DD DT;

*   不可继承 :border padding margin width height ;

*   优先级就近原则,样式定义最近者为准;

*   载入样式以最后载入的定位为准;

优先级为:

   !important >  id > class > tag  

   important 比 内联优先级高

CSS3新增伪类举例:

  • p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。
    
  • p:last-of-type  选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
    
  • p:only-of-type  选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。
    
  • p:only-child    选择属于其父元素的唯一子元素的每个 <p> 元素。
    
  • p:nth-child(2)  选择属于其父元素的第二个子元素的每个 <p> 元素。
    
  • :enabled、:disabled 控制表单控件的禁用状态。
    
  • :checked,单选框或复选框被选中。
    
7、行内元素和块级元素的具体区别是什么?

块级元素的特点:

  • 1.总是从新行开始
  • 2.高度,行高、外边距以及内边距都可以控制。
  • 3.宽度默认是容器的100%
  • 4.可以容纳内联元素和其他块元素。

行内元素的特点:

  • 1.和相邻行内元素在一行上。
  • 2.高、宽无效,但水平方向的padding和margin可以设置,垂直方向的无效。
  • 3.默认宽度就是它本身内容的宽度。
  • 4.行内元素只能容纳文本或则其他行内元素。
8、 rgba()和 opacity 的透明效果有什么不同?

rgba()和 opacity 都能实现透明效果,但最大的不同是 opacity 作用于元素,以及元素内的所有内容的透明度,

而 rgba()只作用于元素的颜色或其背景色。(设置 rgba 透明的元素的子元素不会继承透明效果!)

9、如何垂直居中一个元素

方法一:绝对定位居中(原始版之已知元素的高宽)

.content {
    width: 200px;
    height: 200px;
    background-color: #6699ff;
    position: absolute;
    /*父元素需要相对定位*/
    top: 50%;
    left: 50%;
    margin-top: -100px;
    /*设为高度的1/2*/
    margin-left: -100px;
    /*设为宽度的1/2*/
}

方法二:绝对定位居中(改进版之一未知元素的高宽)

.content {
    width: 200px;
    height: 200px;
    background-color: #6699ff;
    position: absolute;
    /*父元素需要相对定位*/
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /*在水平和垂直方向上各偏移-50%*/
}

方法三:绝对定位居中(改进版之二未知元素的高宽)

.content {
    width: 200px;
    height: 200px;
    background-color: #6699ff;
    margin: auto;
    /*很关键的一步*/
    position: absolute;
    /*父元素需要相对定位*/
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    /*让四个定位属性都为0*/
}

方法四:flex 布局居中

body {
    display: flex;
    /*设置外层盒子display为flex*/
    align-items: center;
    /*设置内层盒子的垂直居中*/
    justify-content: center;
    /*设置内层盒子的水平居中*/
    .content {
        width: 200px;
        height: 200px;
        background-color: #6699ff;
    }
}

那么问题来了,如何垂直居中一个 img(用更简便的方法。)

.content {
    //img的容器设置如下
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
10、BFC
  • 什么是 BFC

    BFC(Block Formatting Context)格式化上下文,是 Web 页面中盒模型布局的 CSS 渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。

  • 形成 BFC 的条件

    • 浮动元素,float 除 none 以外的值
    • 定位元素,position(absolute,fixed)
    • display 为以下其中之一的值 inline-block,table-cell,table-caption
    • overflow 除了 visible 以外的值(hidden,auto,scroll)
  • BFC 的特性

    • 内部的 Box 会在垂直方向上一个接一个的放置。
    • 垂直方向上的距离由 margin 决定
    • bfc 的区域不会与 float 的元素区域重叠。
    • 计算 bfc 的高度时,浮动元素也参与计算
    • bfc 就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。
11、Sass、LESS 是什么?大家为什么要使用他们?

答案:他们是 CSS 预处理器。他是 CSS 上的一种抽象层。他们是一种特殊的语法/语言编译成 CSS。

​ 例如 Less 是一种动态样式语言. 将 CSS 赋予了动态语言的特性,如变量,继承,运算, 函数. LESS 既可以在客户端上运行 (支持 IE 6+, Webkit, Firefox),也可一在服务端运行 (借助 Node. js)。

为什么要使用它们?

  • 结构清晰,便于扩展。
  • 可以方便地屏蔽浏览器私有语法差异。这个不用多说,封装对浏览器语法差异的重复处理,减少无意义的机械劳动。
  • 可以轻松实现多重继承。
  • 完全兼容 CSS 代码,可以方便地应用到老项目中。LESS 只是在 CSS 语法上做了扩展,所以老的 CSS 代码也可以与 LESS 代码一同编译。
stylus/sass/less 区别:

1. 后缀

默认 Sass 使用 . sass 扩展名,而 Less 使用 . less 扩展名,Stylus 默认使用 . styl 的文件扩展名

2. 语法

3. 变量

  • sass 变量必须是以$开头的,然后变量和值之间使用冒号(:)隔开,和 css 属性是一样的
  • Less css 中变量都是用@开头的,其余与 sass 都是一样的
  • stylus 对变量是没有任何设定的,可以是以$开头,或者任何的字符,而且与变量之间可以用冒号,空格隔开,但是在 stylus 中不能用@开头
12、 移动端 1px 问题的解决办法

推荐解决方法:媒体查询 + transfrom

/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
    .border-bottom::after {
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
    .border-bottom::after {
        -webkit-transform: scaleY(0.33);
        transform: scaleY(0.33);
    }
}
13、哪些 css 属性可以继承?

可继承: font-size font-family color, ul li dl dd dt;

不可继承 :border padding margin width height ;

14、几种常见的 CSS 布局
  • 单列布局
  • 两列自适应布局
  • 圣杯布局和双飞翼布局
  • 伪等高布局
  • 粘连布局
15、让 Chrome 支持小于 12px 的文字

谷歌Chrome最小字体是12px,不管你设置成8px还是10px,在浏览器中只会显示12px,那么如何解决这个坑爹的问题呢? 我们的做法是: 针对谷歌浏览器内核,加webkit前缀,用transform:scale()这个属性进行缩放!

<style>
p span{font-size:10px;
  -webkit-transform:scale(0.8);display:block;}
</style>
<p><span>测试10px</span></p>
16、display:inline-block 什么时候会显示间隙?

答案:间隙产生的原因是因为,换行或空格会占据一定的位置

推荐解决方法:

父元素中设置
font-size:0; letter-spaceing:-4px;

17.png、jpg、gif 这些图片格式解释一下,分别什么时候用?,webp 呢

答案:

gif 图形交换格式,索引颜色格式,颜色少的情况下,产生的文件极小,支持背景透明,动画,图形渐进,无损压缩(适合线条,图标等),缺点只有 256 种颜色

jpg 支持上百万种颜色,有损压缩,压缩比可达 180:1,而且质量受损不明显,不支持图形渐进与背景透明,不支持动画

png 为替代 gif 产生的,位图文件,支持透明,半透明,不透明。不支持动画,无损图像格式。Png8 简单说是静态 gif,也只有 256 色,png24 不透明,但不止 256 色。

webp 谷歌开发的旨在加快图片加载速度的图片格式,图片压缩体积是 jpeg 的 2/3,有损压缩。高版本的 W3C 浏览器才支持,google39+,safari7+

结论:JPEG 适合照片,GIF 适合动画,PNG 适合其他任何种类——图表,buttons,背景,图表等等。

18、超链接访问过后 hover 样式就不出现的问题是什么?如何解决?

答案:被点击访问过的超链接样式不在具有 hover 和 active 了, 解决方法是改变 CSS 属性的排列顺序: L-V-H-A(link, visited, hover, active)

19、 css3 有哪些新特性

答案:

1. 选择器

  • E:last-child 匹配父元素的最后一个子元素 E。
  • E:nth-child(n)匹配父元素的第 n 个子元素 E。
  • E:nth-last-child(n) CSS3 匹配父元素的倒数第 n 个子元素 E。

2. RGBA

回答此问题,面试官很可能继续问:rgba()和 opacity 的透明效果有什么不同?

3. 多栏布局

<div class="mul-col">
    <div>
        <h3>新手上路</h3>
        <p>新手专区 消费警示 交易安全 24小时在线帮助 免费开店</p>
    </div>
    <div>
        <h3>付款方式</h3>
        <p>快捷支付 信用卡 余额宝 蚂蚁花呗 货到付款</p>
    </div>
    <div>
        <h3>淘宝特色</h3>
        <p>手机淘宝 旺信 大众评审 B格指南</p>
    </div>
</div>
.mul-col {
    column-count: 3;
    column-gap: 5px;
    column-rule: 1px solid gray;
    border-radius: 5px;
    border: 1px solid gray;
    padding: 10px;
}

4. 多背景图

/* backgroundimage:url('1.jpg),url('2.jpg') */

5. CSS3 word-wrap 属性

p.test {
    word-wrap: break-word;
}

6. 文字阴影

text-shadow: 5px 2px 6px rgba(64, 64, 64, 0.5);

7. @font-face 属性

Font-face 可以用来加载字体样式,而且它还能够加载服务器端的字体文件,让客户端显示客户端所没有安装的字体。

@font-face {
    font-family: BorderWeb;
    src: url(BORDERW0.eot);
}

@font-face {
    font-family: Runic;
    src: url(RUNICMT0.eot);
}

.border {
    font-size: 35px;
    color: black;
    font-family: "BorderWeb";
}

.event {
    font-size: 110px;
    color: black;
    font-family: "Runic";
}

/* 淘宝网字体使用 */

@font-face {
    font-family: iconfont;
    src: url(//at.alicdn.com/t/font_1465189805_4518812.eot);
}

8. 圆角

border-radius: 15px;

9. 边框图片

CSS3 border-image 属性

10.盒阴影

/* box-shadow: 水平方向的偏移量 垂直方向的偏移量 模糊程度 扩展程度 颜色 是否具有内阴影 */

11.盒子大小

​ CSS3 box-sizing 属性

12.媒体查询

​ CSS3 @media 查询

13.CSS3 动画

​ @keyframes

@keyframes abc {
    from {
        transform: rotate(0);
    }

    50% {
        transform: rotate(90deg);
    }

    to {
        transform: rotate(360deg);
    }
}

​ animation 属性

/* animation : name duration timing-function delay interation-count direction play-state */

14、渐变效果

background-image: -webkit-gradient(linear,
    0% 0%,
    100% 0%,
    from(#2a8bbe),
    to(#fe280e));

15.CSS3 弹性盒子模型

  • 弹性盒子是 CSS3 的一种新的布局模式。
  • CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。
  • 引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。

16.CSS3 过渡

div {
    transition: width 2s;
    -moz-transition: width 2s;
    /* Firefox 4 */
    -webkit-transition: width 2s;
    /* Safari 和 Chrome */
    -o-transition: width 2s;
    /* Opera */
}

17.CSS3 变换

  • rotate()旋转
  • translate()平移
  • scale( )缩放
  • skew()扭曲/倾斜
  • 变换基点
  • 3d 转换
20、display 有哪些值?说明他们的作用

默认值:inline

none: 隐藏对象。与visibility属性的hidden值不同,其不为被隐藏的对象保留其物理空间
inline: 指定对象为内联元素。
block: 指定对象为块元素。
list-item: 指定对象为列表项目。
inline-block: 指定对象为内联块元素。(CSS2)
table: 指定对象作为块元素级的表格。类同于html标签

(CSS2)
inline-table: 指定对象作为内联元素级的表格。类同于html标签
(CSS2)
table-caption: 指定对象作为表格标题。类同于html标签(CSS2)
table-row-group: 指定对象作为表格行组。类同于html标签(CSS2)
table-column: 指定对象作为表格列。类同于html标签(CSS2)
table-column-group: 指定对象作为表格列组显示。类同于html标签(CSS2)
table-header-group: 指定对象作为表格标题组。类同于html标签(CSS2)
table-footer-group: 指定对象作为表格脚注组。类同于html标签(CSS2)
run-in: 根据上下文决定对象是内联对象还是块级对象。(CSS3)
box: 将对象作为弹性伸缩盒显示。(伸缩盒最老版本)(CSS3)
inline-box: 将对象作为内联块级弹性伸缩盒显示。(伸缩盒最老版本)(CSS3)
flexbox: 将对象作为弹性伸缩盒显示。(伸缩盒过渡版本)(CSS3)
inline-flexbox: 将对象作为内联块级弹性伸缩盒显示。(伸缩盒过渡版本)(CSS3)
flex: 将对象作为弹性伸缩盒显示。(伸缩盒最新版本)(CSS3)
inline-flex: 将对象作为内联块级弹性伸缩盒显示。(伸缩盒最新版本)(CSS3)
(CSS2)
table-cell: 指定对象作为表格单元格。类同于html标签
(CSS2)
table-row: 指定对象作为表格行。类同于html标签

21、CSS 合并方法

答案:@import url(css 文件地址)

22、CSS 在性能优化方面的实践

1,首推的是合并css文件,如果页面加载10个css文件,每个文件1k,那么也要比只加载一个100k的css文件慢。

2,减少css嵌套,最好不要套三层以上。

3,不要在ID选择器前面进行嵌套,ID本来就是唯一的而且人家权值那么大,嵌套完全是浪费性能。

4,建立公共样式类,把相同样式提取出来作为公共类使用,比如我们常用的清除浮动等。

5,减少通配符*或者类似[hidden=“true”]这类选择器的使用,挨个查找所有… 这性能能好吗?当然重置样式这些必须 的东西是不能少的。

6,巧妙运用css的继承机制,如果父节点定义了,子节点就无需定义。

7,拆分出公共css文件,对于比较大的项目我们可以将大部分页面的公共结构的样式提取出来放到单独css文件里, 这样一次下载后就放到缓存里,当然这种做法会增加请求,具体做法应以实际情况而定。

8,不用css表达式,表达式只是让你的代码显得更加炫酷,但是他对性能的浪费可能是超乎你的想象的。

9,少用css rest,可能你会觉得重置样式是规范,但是其实其中有很多的操作是不必要不友好的,有需求有兴趣的 朋友可以选择normolize. css

10,cssSprite,合成所有icon图片,用宽高加上bacgroud-position的背景图方式显现出我们要的icon图,这是一种 十分实用的技巧,极大减少了http请求。

11,当然我们还需要一些善后工作,CSS压缩(这里提供一个在线压缩 YUI Compressor ,当然你会用其他工具来压缩是十 分好的),

12,GZIP压缩,Gzip是一种流行的文件压缩算法,详细做法可以谷歌或者百度。

23、position 的值, relative 和 absolute 分别是相对于谁进行定位的?
  • absolute : 生成绝对定位的元素, 相对于最近一级的 定位不是 static 的父元素来进行定位。

  • fixed (老 IE 不支持)生成绝对定位的元素,通常相对于浏览器窗口或 frame 进行定位。

  • relative 生成相对定位的元素,相对于其在普通流中的位置进行定位。

  • static 默认值。没有定位,元素出现在正常的流中

  • sticky 生成粘性定位的元素,容器的位置根据正常文档流计算得出

  • static :默认定位属性值。该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, left 和 z-index 属性无效。

  • relative :该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。

  • absolute :不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。

  • fixed :不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed 属性会创建新的层叠上下文。当元素祖先的 transform 属性非 none 时,容器由视口改为该祖先。

24、知道 css 有个 content 属性吗?有什么作用?有什么应用?

答案:知道。css 的 content 属性专门应用在 before/after 伪元素上,用来插入生成内容。最常见的应用是利用伪类清除浮动。

//一种常见利用伪类清除浮动的代码
.clearfix:after {
    content: "."; //这里利用到了content属性
    display: block;
    height: 0;
    visibility: hidden;
    clear: both;
}

.clearfix {
    zoom: 1;
}

after 伪元素通过 content 在元素的后面生成了内容为一个点的块级素,再利用 clear:both 清除浮动。
那么问题继续还有,知道 css 计数器(序列数字字符自动递增)吗?如何通过 css content 属性实现 css 计数器?

答案:css 计数器是通过设置 counter-reset 、counter-increment 两个属性 、及 counter()/counters()一个方法配合 after / before 伪类实现。

25、 使用 CSS 预处理的优缺点分别是什么?

优点:

  • 提高 CSS 可维护性。
  • 易于编写嵌套选择器。
  • 引入变量,增添主题功能。可以在不同的项目中共享主题文件。
  • 通过混合(Mixins)生成重复的 CSS。
  • 将代码分割成多个文件。不进行预处理的 CSS,虽然也可以分割成多个文件,但需要建立多个 HTTP 请求加载这些文件。

缺点:

  • 需要预处理工具。
  • 重新编译的时间可能会很慢。
26、 解释浏览器如何确定哪些元素与 CSS 选择器匹配。

答案:

​ 浏览器从最右边的选择器(关键选择器)根据关键选择器,浏览器从 DOM 中筛选出元素,然后向上遍历被选元素的父元素,判断是否匹配。选择器匹配语句链越短,浏览器的匹配速度越快。

​ 例如,对于形如 p span 的选择器,浏览器首先找到所有 <span> 元素,并遍历它的父元素直到根元素以找到 <p> 元素。对于特定的 <span> ,只要找到一个 <p> ,就知道’`已经匹配并停止继续匹配。

27、translation、transform和translate的区别和联系

transition和transform都是一种动画,translate是transform里的一个属性

1.transition(动画效果)

​ transition(要过渡的属性 花费的时间 运动曲线 何时开始)

要过渡的属性:包括长、宽等等,如果是全部属性,则选择"all"

花费的时间:以"s"为单位,如"0.5s"
运动曲线:默认为ease(慢-快-慢),其他属性还包括linear(匀速)、ease-in(慢-快)、ease-out(快-慢)ease-in-out(慢-快-慢)
何时开始:以"s"为单位,如"0.5s"

通常配合伪类来使用,如下:

<style>
.tr1{

        background-color: chocolate;
        width: 100px;
        height: 100px;
        transition: all 2s ease 0s;
    }
    .tr1:hover{
        width: 200px;
    }
</style>
<body>
    <div class="tr1">hello world</div>
</body>
2.transform:变形。改变
          CSS3中主要包括 旋转:rotate() 顺时针旋转给定的角度,允许负值 rotate(30deg)

          扭曲:skew() 元素翻转给定的角度,根据给定的水平线(X 轴)和垂直线(Y 轴)参数:skew(30deg,20deg)

          缩放:scale() 放大或缩小,根据给定的宽度(X 轴)和高度(Y 轴)参数: scale(2,4)

          移动:translate() 平移,传进 x,y值,代表沿x轴和y轴平移的距离

          所有的2D转换方法组合在一起: matrix()  旋转、缩放、移动以及倾斜元素

           matrix(scale.x ,, , scale.y , translate.x, translate.y)      

改变起点位置 transform-origin: bottom left;

综合起来使用:transform: 30deg 1.5 30deg 20deg 100px 200px;

translate() 方法,元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数:用法transform: translate(50px, 100px)

28、过渡与动画的区别是什么
  • transition

    可以在一定的时间内实现元素的状态过渡为最终状态,用于模拟以一种过渡动画效果,但是功能有限,只能用于制作简单的动画效果而动画属性

  • animation

    可以制作类似 Flash 动画,通过关键帧控制动画的每一步,控制更为精确,从而可以制作更为复杂的动画。

29、文本超出部分显示省略号
// 单行
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
// 多行
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; // 最多显示几行
overflow: hidden;
30、行内元素和块级元素有哪些
行内元素

一个行内元素只占据它对应标签的边框所包含的空间

一般情况下,行内元素只能包含数据和其他行内元素

b, big, i, small, tt
abbr, acronym, cite, code, dfn, em, kbd, strong, samp, var
a, bdo, br, img, map, object, q, script, span, sub, sup
button, input, label, select, textarea
块级元素

占据一整行,高度、行高、内边距和外边距都可以改变,可以容纳块级标签和其他行内标签

header,form,ul,ol,table,article,div,hr,aside,figure,canvas,video,audio,footer
31、::before 和 :after 中双冒号和单冒号有什么区别

在 CSS 中伪类一直用 : 表示,如 :hover, :active 等
伪元素在CSS1中已存在,当时语法是用 : 表示,如 :before 和 :after
后来在CSS3中修订,伪元素用 :: 表示,如 ::before 和 ::after,以此区分伪元素和伪类
由于低版本IE对双冒号不兼容,开发者为了兼容性各浏览器,继续使用 :after 这种老语法表示伪元素
综上所述:::before 是 CSS3 中写伪元素的新语法; :after 是 CSS1 中存在的、兼容IE的老语法

32、解释下css3的flexbox(弹性盒布局模型),以及它应用场景有哪些?

采用Flex布局的元素,称为Flex容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称"项目"。

.box {
	display: flex;
}

行内元素也可以使用Flex布局

.box {
	display:inline-flex;
}

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

三、JavaScript

1、请用 js 去除字符串空格?

答案:replace 正则匹配方法、str. trim()方法、JQ 方法:$. trim(str)方法

解析:

方法一:replace 正则匹配方法

去除字符串内所有的空格:str = str. replace(/\s*/g, “”);

去除字符串内两头的空格:str = str. replace(/^\s*|\s*$/g, “”);

去除字符串内左侧的空格:str = str. replace(/^\s*/, “”);

去除字符串内右侧的空格:str = str. replace(/(\s*$)/g, “”);

方法二:str. trim()方法

trim()方法是用来删除字符串两端的空白字符并返回,trim 方法并不影响原来的字符串本身,它返回的是一个新的字符串。

缺陷:只能去除字符串两端的空格,不能去除中间的空格

方法三:JQ 方法:$. trim(str)方法

$. trim() 函数用于去除字符串两端的空白字符。

注意:$. trim()函数会移除字符串开始和末尾处的所有换行符,空格(包括连续的空格)和制表符。如果这些空白字符在字符串中间时,它们将被保留,不会被移除。

2、js 是一门怎样的语言,它有什么特点

1. 脚本语言。JavaScript 是一种解释型的脚本语言, C、C++等语言先编译后执行, 而 JavaScript 是在程序的运行过程中逐行进行解释。

2. 基于对象。JavaScript 是一种基于对象的脚本语言, 它不仅可以创建对象, 也能使用现有的对象。

3. 简单。JavaScript 语言中采用的是弱类型的变量类型, 对使用的数据类型未做出严格的要求, 是基于 Java 基本语句和控制的脚本语言, 其设计简单紧凑。

4. 动态性。JavaScript 是一种采用事件驱动的脚本语言, 它不需要经过 Web 服务器就可以对用户的输入做出响应。

5. 跨平台性。JavaScript 脚本语言不依赖于操作系统, 仅需要浏览器的支持。

3、== 和 === 的不同

== 是抽象相等运算符,而 === 是严格相等运算符。 == 运算符是在进行必要的类型转换后,再比较。 === 运算符不会进行类型转换,所以如果两个值不是相同的类型,会直接返回 false

4、事件冒泡和事件委托

事件冒泡:当一个子元素的事件被触发的时候(例如onclick事件),该事件会从事件(被电击的元素)开始逐个向上传播,触发父级元素的点击事件。

事件委托 :将子元素的事件通过冒泡的形式交由父元素来执行。比如我们平时在给ul中的li添加事件的时候,我们都是通过for循环一个个添加,如果li很多个的话,其实就有点占内存了,这个时候可以用 事件代理来优化性能。

var ul = document.getElementById('parentUl');  
 ul.οnclick=function (event) {  
	var e = event||window.event,  
    source = e.target || e.srcElement;//target表示在事件冒泡中触发事件的源元素,在IE中是srcElement  
    if(source.nodeName.toLowerCase() == "li"){   //判断只有li触发的才会输出内容  
    alert(source.innerHTML);  
     }  
 		stopPropagation(e);      //阻止继续冒泡  
  };  

   function addElement() {  
    var li = document.createElement('li');  
   		li.innerHTML="我是新孩子";  
  		ul.appendChild(li);  
    } 
5、click()和onclick()

onclick()是绑定事件:作用执行函数代码;
click()本身是方法:作用是触发onclick()事件

<script type="text/javascript"> 
$(function(){
	$("#b2").click(function(){
	$("#b1").click();
});});
function change(){
	alert("调用了方法change");
}

</script> 
<button id = "b1" onclick="change()">按钮1</button>
<button id = "b2">按钮2</button>
6、require 与 import 的区别

答案:两者的加载方式不同、规范不同

第一、两者的加载方式不同,require 是在运行时加载,而 import 是在编译时加载

require(’. /a’)(); // a 模块是一个函数,立即执行 a 模块函数

var data = require(’. /a’). data; // a 模块导出的是一个对象

var a = require(’. /a’)[0]; // a 模块导出的是一个数组==>哪都行

import $ from ‘jquery’;

import * as _ from ‘_’;

import {a, b, c} from ‘. /a’;

import {default as alias, a as a_a, b, c} from ‘. /a’; ==>用在开头

第二、规范不同,require 是 CommonJS/AMD 规范,import 是 ESMAScript6+规范

第三、require 特点:社区方案,提供了服务器/浏览器的模块加载方案。非语言层面的标准。只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化。

import 特点:语言规格层面支持模块功能。支持编译时静态分析,便于 JS 引入宏和类型检验。动态绑定。

7、javascript 对象的几种创建方式

第一种:Object 构造函数创建

第二种:使用对象字面量表示法

第三种:使用工厂模式创建对象

第四种: 使用构造函数创建对象

第五种:原型创建对象模式

第六种:组合使用构造函数模式和原型模式

8、什么是原型链?

答案:通过一个对象的__proto__可以找到它的原型对象,原型对象也是一个对象,就可以通过原型对象的__proto__,最后找到了我们的 Object. prototype, 从实例的原型对象开始一直到 Object. prototype 就是我们的原型链

9、 javascript 的 typeof 返回哪些数据类型

​ 7 种分别为 string、boolean、number、Object(对象,数组,null)、Function、undefined、symbol(ES6)

JavaScript 的数据类型

答案:JS 数据类型共有六种,分别是 String、Number、Boolean、Null、Undefined 和 Object 等, 另外,ES6 新增了 Symbol 类型。其中,Object 是引用数据类型,其他的都是基本数据类型(Primitive Type)。

10、如何判断 JS 变量的一个类型(至少三种方式)

答案:typeof、instanceof、 constructor、 prototype

11、 列举 3 种强制类型转换和 2 种隐式类型转换

答案:强制: parseInt(), parseFloat(), Number(), Boolean(), String()

​ 隐式: +, -

12、你对闭包的理解?优缺点?

概念:闭包就是能够读取其他函数内部变量的函数。

三大特性:

  • 函数嵌套函数。
  • 函数内部可以引用外部的参数和变量。
  • 参数和变量不会被垃圾回收机制回收。

优点:

  • 希望一个变量长期存储在内存中。
  • 避免全局变量的污染。
  • 私有成员的存在。

缺点:

  • 常驻内存,增加内存使用量。
  • 使用不当会很容易造成内存泄露。
13、for in 和 for of的区别

for in

  1. 一般用于遍历对象的可枚举属性。以及对象从构造函数原型中继承的属性。对于每个不同的属性,语句都会被执行。

  2. 不建议使用 for in 遍历数组,因为输出的顺序是不固定的。

  3. 如果迭代的对象的变量值是 null 或者 undefined, for in 不执行循环体,建议在使用 for in 循环之前,先检查该对象的值是不是 null 或者 undefined。

for of

  • for…of 语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。
14、如何判断一个对象是否为数组

第一种方法:使用 instanceof 操作符。

第二种方法:使用 ECMAScript 5 新增的 Array. isArray()方法。

第三种方法:使用使用 Object. prototype 上的原生 toString()方法判断。

15、Object. prototype. toString. call() 和 instanceOf 和 Array. isArray() 区别好坏

答案:

  • Object. prototype. toString. call()
    • 优点:这种方法对于所有基本的数据类型都能进行判断,即使是 null 和 undefined 。
    • 缺点:不能精准判断自定义对象,对于自定义对象只会返回[object Object]
  • instanceOf
    • 优点:instanceof 可以弥补 Object. prototype. toString. call()不能判断自定义实例化对象的缺点。
    • 缺点: instanceof 只能用来判断对象类型,原始类型不可以。并且所有对象类型 instanceof Object 都是 true,且不同于其他两种方法的是它不能检测出 iframes。
  • Array. isArray()
    • 优点:当检测 Array 实例时,Array. isArray 优于 instanceof ,因为 Array. isArray 可以检测出 iframes
    • 缺点:只能判别数组
16、面向对象和面向过程的异同
  • 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
  • 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

面向对象的三个基本特征是:封装、继承、多态。

封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。

封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

继承 是指这样一种能力:在一个类的基础上创建一个新的类,它拥有之前类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

多态(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

17、 JS 块级作用域、变量提升

1. 块级作用域

​ JS 中作用域有:全局作用域、函数作用域。没有块作用域的概念。ECMAScript 6(简称 ES6)中新增了块级作用域。块作用域由 { } 包括,if 语句和 for 语句里面的{ }也属于块作用域。

2. 变量提升

  • 如果变量声明在函数里面,则将变量声明提升到函数的开头
  • 如果变量声明是一个全局变量,则将变量声明提升到全局作用域的开头
解释 JavaScript 中的作用域与变量声明提升?
  • 作用域只会对某个范围产生作用,而不会对外产生影响的封闭空间。在这样的一些空间里,外 部不能访问内部变量,但内部可以访问外部变量。
  • 所有申明都会被提升到作用域的最顶上
  • 同一个变量申明只进行一次,并且因此其他申明都会被忽略
  • 函数声明的优先级优于变量申明,且函数声明会连带定义一起被提升
18、var、let、const 的区别
  • var 定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
  • let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
  • const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。
  • 同一个变量只能使用一种方式声明,不然会报错
19、 null/undefined 的区别

null: Null 类型,代表“空值",代表一个空对象指针,使用 typeof 运算得到 “object",所以你可以认为它是一个特殊的对象值。

undefined: Undefined 类型,当一个声明了一个变量未初始化时,得到的就是 undefined。

20、JS 哪些操作会造成内存泄露

1)意外的全局变量引起的内存泄露

2)闭包引起的内存泄露

3)没有清理的 DOM 元素引用

4)被遗忘的定时器或者回调

5)子元素存在引起的内存泄露

6)IE7/8 引用计数使用循环引用产生的问题

21、 jsonp 优缺点
  • 优点

    1. 1 它不像 XMLHttpRequest 对象实现的 Ajax 请求那样受到同源策略的限制,JSONP 可以跨越同源策略;

    2. 2 它的兼容性更好,在更加古老的浏览器中都可以运行,不需要 XMLHttpRequest 或 ActiveX 的支持

    3. 3 在请求完毕后可以通过调用 callback 的方式回传结果。将回调方法的权限给了调用方。这个就相当于将 controller 层和 view 层终于分 开了。我提供的 jsonp 服务只提供纯服务的数据,至于提供服务以 后的页面渲染和后续 view 操作都由调用者来自己定义就好了。如果有两个页面需要渲染同一份数据,你们只需要有不同的渲染逻辑就可以了,逻辑都可以使用同 一个 jsonp 服务。

  • 缺点

    1. 1 它只支持 GET 请求而不支持 POST 等其它类型的 HTTP 请求

    2. 2 它只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面之间如何进行 JavaScript 调用的问题。

    3. 3 jsonp 在调用失败的时候不会返回各种 HTTP 状态码。

    4. 4 缺点是安全性。万一假如提供 jsonp 的服务存在页面注入漏洞,即它返回的 javascript 的内容被人控制的。那么结果是什么?所有调用这个 jsonp 的网站都会存在漏洞。于是无法把危险控制在一个域名下…所以在使用 jsonp 的时候必须要保证使用的 jsonp 服务必须是安全可信的

22、this指向问题
  • 解析器在调用函数时,每次都会向函数内部传递进一个隐含的参数,这个参数就是this

    this指向的是一个对象,对象称为函数执行的上下文对象

  • 根据函数调用的方式不同,this指向不同的对象
    1、以函数形式调用时,this永远都是window
    2、以方法形式调用时,this就是调用方法的对象

  • this的情况:
    1、当以函数的形式调用时,this就是window,
    2、当以方法的形式调用时,谁调用方法this就是谁,
    3、当以构造函数的形式调用时,this就是新创建的那个对象
    4、使用call和apply调用时,this是指定的那个对象

23、 call() 和 apply() 的含义和区别?

首先说明两个方法的含义:

  • call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B. call(A, args1, args2); 即 A 对象调用 B 对象的方法。
  • apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B. apply(A, arguments); 即 A 对象应用 B 对象的方法。

call 与 apply 的相同点:

  • 方法的含义是一样的,即方法功能是一样的;
  • 第一个参数的作用是一样的;

call 与 apply 的不同点:两者传入的列表形式不一样

  • call 可以传入多个参数;
  • apply 只能传入两个参数,所以其第二个参数往往是作为数组形式传入

call 和 apply 其实是一样的,区别就在于传参时参数是一个一个传或者是以一个数组的方式来传。
call 和 apply 都是在调用时生效,改变调用者的 this 指向

bind 也是改变 this 指向,不过不是在调用时生效,而是返回一个新函数。

let name = 'Jack'
const obj = {name: 'Tom'}
function sayHi() {console.log('Hi! ' + this.name)}
sayHi() // Hi! Jack

sayHi.call(obj) // Hi! Tom
const newFunc = sayHi.bind(obj)
24、new 操作符具体干了什么呢?

new 共经过了 4 个阶段

  • 1、创建一个空对象
  • 2、设置原型链
  • 3、让 Func 中的 this 指向 obj,并执行 Func 的函数体
  • 4、判断 Func 的返回值类型:
25、事件绑定与普通事件有什么区别
  • 用普通事件添加相同事件,下面会覆盖上面的,而事件绑定不会
  • 普通事件是针对非 dom 元素,事件绑定是针对 dom 元素的事件
26、 javascript 的同源策略

同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。
这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。
指一段脚本只能读取来自同一来源的窗口和文档的属性。

27、事件冒泡与事件捕获

事件冒泡:由最具体的元素(目标元素)向外传播到最不具体的元素

事件捕获:由最不确定的元素到目标元素

28、 js 中 callee 与 caller 的作用

1. caller 返回一个调用当前函数的引用 如果是由顶层调用的话 则返回 null
2. callee 返回一个正在被执行函数的引用 (这里常用来递归匿名函数本身 但是在严格模式下不可行)

29、说说你对作用域链的理解

答案:作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到 window 对象即被终止,作用域链向下访问变量是不被允许的。

30、 Js 动画与 CSS 动画区别及相应实现

CSS3的动画的优点:在性能上会稍微好一些,浏览器会对CSS3的动画做一些优化,代码相对简单
缺点:在动画控制上不够灵活,兼容性不好

JavaScript的动画正好弥补了这两个缺点,控制能力很强,可以单帧的控制、变换,同时写得好完全可以兼容IE6,并且功能强大。对于一些复杂控制的动画,使用javascript会比较靠谱。

31、定时器 setInterval 有一个有名函数 fn1,setInterval(fn1, 500)与 setInterval(fn1(), 500)有什么区别?

答案:第一个是重复执行每 500 毫秒执行一次,后面一个只执行一次。

32、你用过 require. js 吗?它有什么特性?

(1)实现 js 文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。

33、对象浅拷贝和深拷贝有什么区别

​ 浅拷贝可以使用列表自带的copy()函数(如list.copy()),或者使用copy模块的copy()函数。深拷贝只能使用copy模块的deepcopy(),所以使用前要导入:from copy import deepcopy
​ 如果拷贝的对象里的元素只有值,没有引用,那浅拷贝和深拷贝没有差别,都会将原有对象复制一份,产生一个新对象,对新对象里的值进行修改不会影响原有对象,新对象和原对象完全分离开。
如果拷贝的对象里的元素包含引用(像一个列表里储存着另一个列表,存的就是另一个列表的引用),那浅拷贝和深拷贝是不同的,浅拷贝虽然将原有对象复制一份,但是依然保存的是引用,所以对新对象里的引用里的值进行修改,依然会改变原对象里的列表的值,新对象和原对象完全分离开并没有完全分离开。而深拷贝则不同,它会将原对象里的引用也新创建一个,即新建一个列表,然后放的是新列表的引用,这样就可以将新对象和原对象完全分离开。

34、如何编写高性能的 Javascript?
  • 使用 DocumentFragment 优化多次 append
  • 通过模板元素 clone ,替代 createElement
  • 使用一次 innerHTML 赋值代替构建 dom 元素
  • 使用 firstChild 和 nextSibling 代替 childNodes 遍历 dom 元素
  • 使用 Array 做为 StringBuffer ,代替字符串拼接的操作
  • 将循环控制量保存到局部变量
  • 顺序无关的遍历时,用 while 替代 for
  • 将条件分支,按可能性顺序从高到低排列
  • 在同一条件子的多( >2 )条件分支时,使用 switch 优于 if
  • 使用三目运算符替代条件分支
  • 需要不断执行的时候,优先考虑使用 setInterval
35、documen. write 和 innerHTML 的区别?

1. document. write 是重写整个 document, 写入内容是字符串的 html
2. innerHTML 是 HTMLElement 的属性,是一个元素的内部 html 内容

36、requireJS 的核心原理是什么?(如何动态加载的?如何避免多次加载的?如何缓存的?)

答案:核心是 js 的加载模块,通过正则匹配模块以及模块的依赖关系,保证文件加载的先后顺序,根据文件的路径对加载过的文件做了缓存

37、事件绑定的方式
  • 嵌入 dom
<button onclick="func()">按钮</button>
  • 直接绑定
btn.onclick = function() {};
  • 事件监听
btn.addEventListener("click", function() {});
38、target 和 currentTarget 区别
  • event. target:返回触发事件的元素
  • event. currentTarget:返回绑定事件的元素
39、prototype 和__proto__的关系是什么

所有的对象都拥有__proto__属性,它指向对象构造函数的 prototype 属性

所有的函数都同时拥有__proto__和 protytpe 属性
函数的__proto__指向自己的函数实现 函数的 protytpe 是一个对象 所以函数的 prototype 也有__proto__属性 指向 Object. prototype,Object. prototype. __proto__指向 null

40、forEach,map和filter的区别(哔哩哔哩)
  • filter函数,顾名思义,它是一个用来过滤的函数。他可以通过指定的过滤条件,删选出数组中符合条件的元素,并返回。
  • map函数,这个函数与filter函数不同之处在于,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。而map则会返回传入函数return的值。
  • forEach函数,可以实现对数组的遍历,和map函数与filter函数不同的是它没有返回值。
41、for和forEach的区别

1、foreach
定义:foreach又叫做增强for循环,相当于for循环的简化版,因此在一些较复杂的循环中不适用。
结构:foreach(元素类型 元素名称:循环对象(数组、集合)){
​ 循环语句
}
特点:foreach在循环次数未知或者计算起来较复杂的情况下效率比for循环高。

2、foreach与for循环的明显差别在于foreach循环时循环对象(数组、集合)被锁定,不能对循环对象中的内容进行增删改操作。

  // for循环:可以修改循环语句
var array = ["a","b","c","d"];
for (var i = 0; i < array.length; i ++) {
  array[i] = "A";
};
console.log(array);     // 结果:"A" "A" "A" "A"

// foreach循环:不能修改循环语句
var array2 =  ["a","b","c","d"];
array2.forEach(function(item) {
  item = "A";
});
console.log(array2);    // 结果:["a","b","c","d"]
42、数组中的forEach和map的区别

相同点:

  • 都是循环遍历数组中的每一项
  • forEach和map方法里每次执行匿名函数都支持3个参数,参数分别是item(当前每一项),index(索引值),arr(原数组)
  • 匿名函数中的this都是指向window
  • 只能遍历数组
  • 都不会改变原数组

区别:

map方法:
1.map方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值。
2.map方法不会对空数组进行检测,map方法不会改变原始数组。
3.浏览器支持:chrome、Safari1.5+、opera都支持,IE9+,
array.map(function(item, index, arr) {}, thisValue)

var arr = [0, 2, 4, 6, 8];
var str = arr.map(function(item, index, arr) {
    console.log(this); //window
    console.log("原数组arr:", arr); //注意这里执行5次
    return item / 2;
}, this);
console.log(str); //[0,1,2,3,4]

若arr为空数组,则map方法返回的也是一个空数组。

forEach方法:

1. forEach方法用来调用数组的每个元素,将元素传给回调函数
2. forEach对于空数组是不会调用回调函数的。

Array.forEach(function(item, index, arr) {}, this)
var arr = [0, 2, 4, 6, 8];
var sum = 0;
var str = arr.forEach(function(item, index, arr) {
    sum += item;
    console.log("sum的值为:", sum); //0 2 6 12 20
    console.log(this); //window
}, this)
console.log(sum); //20
console.log(str); //undefined

无论arr是不是空数组,forEach返回的都是undefined。这个方法只是将数组中的每一项作为callback的参数执行一次。

43、for in和for of的区别
简单总结就是,for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。
for-in总是得到对象的key或数组、字符串的下标。
for-of总是得到对象的value或数组、字符串的值,另外还可以用于遍历Map和Set。
44、JavaScript 中 undefined 和 not defined 的区别

答案:undefined是没有初始化,not defined是没有声明

45、什么是跨域?跨域请求资源的方法有哪些?

跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。

同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。
存在跨域的情况:
网络协议不同,如http协议访问https协议。
端口不同,如80端口访问8080端口。
域名不同,如qianduanblog.com访问baidu.com。
子域名不同,如abc.qianduanblog.com访问def.qianduanblog.com。
域名和域名对应ip,如www.a.com访问20.205.28.90.

跨域请求资源的方法:
porxy代理、CORS跨域资源共享 (Cross-origin resource sharing)、jsonp
1.porxy代理
定义:proxy代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。
实现方法:通过nginx代理;
注意点:如果你代理的是https协议的请求,那么你的proxy首先需要信任该证书或者忽略证书检查,否则你的请求无法成功。

2.CORS跨域资源共享 (Cross-origin resource sharing)
定义:是现代浏览器支持跨域资源请求的一种最常用的方式。
使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作:代码如下

var express = require('express');
var app = express();
var allowCrossDomain = function (req, res, next) {
  res.header('Access-Control-Allow-Origin', 'http://localhost:3001');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
}
app.use(allowCrossDomain);

3.jsonp
定义和用法:通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行。
特点:通过动态创建script来读取他域的动态资源,获取的数据一般为json格式。

<script>
    function testjsonp(data) {
       console.log(data.name); // 获取返回的结果
    }
</script>
<script>
    var scripts = document.createElement('script');
    scripts.type = "text/javascript";
    scripts.src = "http://localhost:8888/jsonp?callback=testjsonp";
    document.head.appendChild(scripts);
</script>

缺点 :这种方式只支持get请求,无法发送post请求;

如何解决跨域问题?
  1. jsonp ,允许 script 加载第三方资源
  2. 反向代理(nginx 服务内部配置 Access-Control-Allow-Origin *)
  3. cors 前后端协作设置请求头部,Access-Control-Allow-Origin 等头部信息
  4. iframe 嵌套通讯,postmessage
46、Cookie、session和localStorage、以及sessionStorage之间的区别

cookie和session的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上
2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session
3、session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
5、建议将登录信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中
6、session保存在服务器,客户端不知道其中的信心;cookie保存在客户端,服务器能够知道其中的信息
7、session中保存的是对象,cookie中保存的是字符串
8、session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到,而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的

sessionStorage、localStorage和cookie的区别
共同点:都是保存在浏览器端、且同源的
区别:
1、cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
2、存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
3、数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
4、作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
5、web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
6、web Storage的api接口使用更方便

47、typeof 与 instanceof 区别
1、typeof返回结果是该类型的字符串形式表示【6】(number、string、undefined、boolean、function、object)
2、instanceof是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型。 

48、微任务和宏任务
/*
 * 宏任务
 *   分类: setTimeout setInterval requrestAnimationFrame
 *   1. 宏任务所处的队列就是宏任务队列
 *   2. 第一个宏任务队列中只有一个任务: 执行主线程的js代码
 *   3. 宏任务队列可以有多个
 *   4. 当宏任务队列的中的任务全部执行完以后会查看是否有微任务队列如果有先执行微任务队列中的所有任务,如果没有就查看是否有宏任务队列
 *
 * 微任务
 *   分类: new Promise().then(回调) process.nextTick
 *   1. 微任务所处的队列就是微任务队列
 *   2. 只有一个微任务队列
 *   3. 在上一个宏任务队列执行完毕后如果有微任务队列就会执行微任务队列中的所有任务
 * */

console.log('----------------- start -----------------');

setTimeout(() => {
    console.log('setTimeout');
}, 0)

new Promise((resolve, reject) => {
    for (var i = 0; i < 5; i++) {
        console.log(i);
    }
    resolve(); // 修改promise实例对象的状态为成功的状态
}).then(() => {
    console.log('promise实例成功回调执行');
})

console.log('----------------- end -----------------');

四、ajax

1、GET 和 POST 的区别,何时使用 POST?

GET:一般用于信息获取,使用 URL 传递参数,对所发送信息的数量也有限制,一般在 2000 个字符,有的浏览器是 8000 个字符

POST:一般用于修改服务器上的资源,对所发送的信息没有限制

在以下情况中,请使用 POST 请求:

  1. 无法使用缓存文件(更新服务器上的文件或数据库)
  2. 向服务器发送大量数据(POST 没有数据量限制)
  3. 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
2、 ajax 请求的时候 get 和 post 方式的区别

get 一般用来进行查询操作,url 地址有长度限制,请求的参数都暴露在 url 地址当中,如果传递中文参数,需要自己进行编码操作,安全性较低。

post 请求方式主要用来提交数据,没有数据长度的限制,提交的数据内容存在于 http 请求体中,数据不会暴漏在 url 地址中。

3、 一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?
  1. 浏览器地址栏输入 url
  2. 浏览器会先查看浏览器缓存–系统缓存–路由缓存,如有存在缓存,就直接显示。如果没有,接着第三步
  3. 域名解析(DNS)获取相应的 ip
  4. 浏览器向服务器发起 tcp 连接,与浏览器建立 tcp 三次握手
  5. 握手成功,浏览器向服务器发送 http 请求,请求数据包
  6. 服务器请求数据,将数据返回到浏览器
  7. 浏览器接收响应,读取页面内容,解析 html 源码,生成 DOm 树
  8. 解析 css 样式. 浏览器渲染,js 交互绑定多个域名,数量不限;
4、AMD 和 CMD 规范的区别

​ AMD 是 RequireJS 在推广过程中对模块定义提出的概念。
​ CMD 是 SeaJS 在推广过程中对模块定义提出的概念。

  1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行
  2. CMD 推崇依赖就近,AMD 推崇依赖前置
5、HTTP 状态码

100 ? Continue ? 继续,一般在发送 post 请求时,已发送了 http header 之后服务端将返回此信息,表示确认,之后发送具体参数信息(正在请求)

200 ? OK ? 正常返回信息(成功)

201 ? Created ? 请求成功并且服务器创建了新的资源

202 ? Accepted ? 服务器已接受请求,但尚未处理

301 ? Moved Permanently ? 请求的网页已永久移动到新位置。

302 Found ? 临时性重定向。

303 See Other ? 临时性重定向,且总是使用 GET 请求新的 URI。

304 ? Not Modified ? 自从上次请求后,请求的网页未修改过。

400 Bad Request ? 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。

401 Unauthorized ? 请求未授权。

403 Forbidden ? 禁止访问。

404 Not Found ? 找不到如何与 URI 相匹配的资源。

500 Internal Server Error ? 最常见的服务器端错误。

503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。

6、栈和队列的区别?
  • 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。
  • 队列先进先出,栈先进后出。
  • 栈只允许在表尾一端进行插入和删除,而队列只允许在表尾一端进行插入,在表头一端进行删除
7、说说你对 promise 的了解

答案:Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件监听——更合理和更强大。

​ 所谓 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise 对象有以下两个特点:

  1. 对象的状态不受外界影响,Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)
  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。

promise构造函数是同步执行的,then方法是异步执行的

8、解构赋值及其原理

解构赋值:其实就是分解出一个对象的解构,分成两个步骤:

  1. 变量的声明
  2. 变量的赋值

原理:ES6 变量的解构赋值本质上是“模式匹配”, 只要等号两边的模式相同,左边的变量就会被赋予匹配的右边的值,如果匹配不成功变量的值就等于 undefined

9、Array. from() 与 Array. reduce()

Array. from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组
Array. reduce()方法对累加器和数组中的每个元素 (从左到右)应用一个函数,将其减少为单个值。

10、箭头函数和普通函数有什么区别

箭头函数是普通函数的简写,可以更优雅的定义一个函数,和普通函数相比,有以下几点差异:

1、箭头函数体内的 this 对象,是定义时所在的对象,而不是使用时所在的对象。

2、不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

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

4、不可以使用 new 命令,因为:

​ 没有自己的 this,无法调用 call,apply。
​ 没有 prototype 属性 ,而 new 命令在执行时需要将构造函数的 prototype 赋值给新的对象的 proto

11、设计并实现 Promise. race()
Promise._race = promises => new Promise((resolve, reject) => {
    promises.forEach(promise => {
        promise.then(resolve, reject)
    })
})
11、setTimeout、Promise、Async/Await 的区别

这题主要是考察这三者在事件循环中的区别,事件循环中分为宏任务队列和微任务队列。

  • 其中settimeout的回调函数放到宏任务队列里,等到执行栈清空以后执行;
  • promise. then里的回调函数会放到相应宏任务的微任务队列里,等宏任务里面的同步代码执行完再执行;
  • async函数表示函数里面可能会有异步方法,await后面跟一个表达式,async方法执行时,遇到await会立即执行表达式,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行。
  • 10
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值