1.如何理解html标签语义化?
合理的标签做合理的事情, 能让浏览器更好的读取页面结构, 便于团队开发和维护, 有利于SEO, 常用的语义化标签包括:
<header></header>头部
<nav></nav>导航栏
<section></section>区块(有语义化的div)
<main></main>主要区域
<article></article>主要内容
<aside></aside>侧边栏
<footer></footer>底部
2.css权重是什么?
设置节点样式的方式有很多种,不同的方式它们的权重并不相同,当它们给一个节点设置同一个样式时,谁的权重高谁就生效。
- important:无限高
- 行内样式:权重值为1000
- id选择器:权重值为100
- 类、伪类、属性选择器:权重值为10
- 标签选择器:权重值为1
3.盒模型有几种,它们区别是什么?
content、padding、border、margin
- 标准盒模型(box-sizing:content-box)
- ie怪异盒模型(box-sizing:border-box)
- flex弹性伸缩盒模型
- column多列布局(栅格化布局 基本不用)
- 注:怪异盒模型的好处,固定到border控制宽高,不用重新计算padding和border
4. 什么是BFC?
块级格式上下文,一句话来说就是让块级元素有块级元素该有的样子,触发BFC可以清除浮动、让margin不重叠。
- float的值不为none。(left、right)
- position的值不为static或relative中的任何一个。(absolute、fixed)
- overflow的值不为visible。(hidden、auto、scroll)
- display的值为table-cell、table-caption和inline-block之一。
5. px、em、rem、vw/vh的区别?
- px:物理屏幕上能显示出的最小的一个点。
- em:如果父级有设置字体大小,1em就是父级的大小,没有1em等于自身默认的字体大小。
- rem:相对于html标签的字体大小。
- vw/vh:相对于视口的高度和宽度,1vh 等于1/100的视口高度,1vw 等于1/100的视口宽度。
6. 不使用border属性画一条1px的线?
<div style='height: 1px; background: #666; overflow: hidden;'></div>
<hr size='1'></hr>
7. 移动端1px问题的解决办法
8. 定位的方式有哪几种,它们的区别是什么?
- relative:相较于自身定位,设置的位置相对于自己进行位移。不脱离文档流。
- absolute:相较于最近有定位的父节点定位,设置的位置相较于父节点。会脱离文档流,导致父节点高度塌陷。
- fixed:相较于当前窗口进行定位,设置的位置相较于窗口。脱离文档流。
- static:默认值。没有定位,元素出现在正常的流中。
- sticky:生成粘性定位的元素,容器的位置根据正常文档流计算得出。
- 粘性定位:www.jianshu.com/p/e25a9eb8a…
9. 垂直水平居中的实现方式有哪些?
- 父级设置text-align: center和line-height等同高度。
- 子节点绝对定位,设置position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);
- 子节点绝对定位,需要设置宽度和高度。设置position: absolute;top:0;left:0;right:0;bottom:0;margin:auto;
- 父级设置display: table; 子节点设置display:table-cell;text-align:center;vertical-align:middle;
- 父级设置display: flex;justify-content:center;align-items:center;
- 父节点设置display: grid; 子节点设置:align-self:center;justify-self: center;
10.你知道的左右宽度固定,中间自适应的三栏布局方案有哪些?
浮动:
.parent {overflow: hidden;}
.left {float: left; width: 100px;}
.right: {float: right; width: 100px;}
<div class='parent'>
<div class='left'></div>
<div class='right'></div>
<div class='center'></div>
</div>
定位1:
.parent {position: relative};
.left {position: absolute; left: 0; width: 100px};
.right {position: absolute; right: 0; width: 100px};
.center {postion: absolute; left: 100px; right: 100px};
定位2:
.parent {position: relative};
.left {position: absolute; left: 0; width: 100px};
.right {position: absolute; right: 0; top: 0; width: 100px};
.center {margin: 0 100px 0 100px};
表格:
.parent {dispaly: table; width: 100%;}
.left {display: table-cell; width: 100px;}
.center {display: table-cell;}
.right {display: table-cell; width: 100px;}
弹性:
.parent {display: flex;}
.left {width: 100px;}
.center {flex: 1;}
.right {width: 100px;}
网格:
.parent {
display: grid;
width: 100%;
grid-template-rows: 100px;
grid-template-columns: 100px auto 100px;
}
11.实现三个圆形的水平自适应布局?
难点在于高度的自适应
.parent {
display: table;
width: 100%;
}
.child {
display: table-cell;
padding-top: 33.33%;
background: red;
border-radius: 50%;
}
.parent {
overflow: hidden;
}
.child {
float: left;
width: 33.33%;
padding-top: 33.33%;
border-radius: 50%;
background: red;
}
.parent {
display: flex;
}
.child {
flex: 1;
padding-top: 33.33%;
border-radius: 50%;
background: red;
}
12.介绍下flex布局?
主轴方向:水平排列(默认) | 水平反向排列 | 垂直排列 | 垂直反向排列
flex-direction: row | row-reverse | column | column-reverse;
换行:不换行(默认) | 换行 | 反向换行(第一行在最后面)
flex-wrap: nowrap | wrap | wrap-reverse;
flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
flex-flow: <flex-direction> || <flex-wrap>;
主轴对齐方式:起点对齐(默认) | 终点对齐 | 居中对齐 | 两端对齐 | 分散对齐
justify-content: flex-start | flex-end | center | space-between | space-around;
交叉轴对齐方式:拉伸对齐(默认) | 起点对齐 | 终点对齐 | 居中对齐 | 第一行文字的基线对齐
align-items: stretch | flex-start | flex-end | center | baseline;
多根轴线对齐方式:拉伸对齐(默认) | 起点对齐 | 终点对齐 | 居中对齐 | 两端对齐 | 分散对齐
align-content: stretch | flex-start | flex-end | center | space-between | space-around;
13.JavaScript的变量有哪些类型?
分为两种:基础类型和引用类型。
- 基础类型:boolean、null、undefined、number、string、symbol(创建唯一值的)。
- 引用类型:Array、Object、Function。
14.基础类型和引用的区别?
- 它们在内存中存储的方式不同。基础类型存储的是值,而引用类型存储的是指向内存中某个空间的指针;
- 基础类型赋值就是把值赋给另外一个变量,而引用类型的赋值是赋值的原来变量的指针,所以当引用类型发生改变时,只要是指向同一个指针的变量的都会发生改变。
15.函数参数是对象时会发生什么问题?
- 函数参数是对象时,相当于是将对象的指针传递给了函数,如果在函数的内部改变了对象的值,外面对象的值也会发生改变,数组也是如此。
16.typeof和instanceof判断变量类型的区别?
- typeof对于基础类型除了null以外都可以显示正确的类型,对于数组和对象都会显示object,对于函数会显示function。
- instanceof主要是用来判断引用类型,它的原理是根据原型链来查找。
17.有没有更好的判断变量类型的方法?
- 可以使用Object.prototype.toString.call(var),可以更加准确的判断某个变量的类型。
18.类数组转为数组的方式有哪些?
[].slice.call(arguments)
Array.from(arguments)
[...arguments]
19.如何判断一个变量是否是数组?
arr instanceof Array
Array.prototype.isPrototypeOf(arr)
Array.isArray(arr)
Object.prototype.toString.call(arr) === '[object Array]'
arr.constructor === Array
20.将多维数组扁平化?
function flatten(arr) {
return [].concat(...arr.map(v => {
return Array.isArray(v) ? flatten(v) : v;
}))
}
function flatten(arr) {
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
}, [])
}
function flatten(arr) {
return arr.flat(Infinity);
}
function flatten(arr) { // 纯数字
return arr.toString().split(',').map(Number);
}
function flatten(arr) {
const ret = [];
while (arr.length) {
const item = arr.shift();
if (Array.isArray(item)) {
arr.unshift(...item);
} else {
ret.push(item);
}
}
return ret;
}
21.数组去重?
- 一、利用ES6 Set去重(ES6中最常用)
function unique (arr) {
return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
这种去重的方法代码最少,但是无法去掉“{}”空对象
- 二、利用for嵌套for,然后splice去重(ES5中最常用)
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]==arr[j]){ //第一个等同于第二个,splice方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}] //NaN和{}没有去重,两个null直接消失了
注:双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。
- 三、利用indexOf去重:新建一个空的结果数组,for循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (array .indexOf(arr[i]) === -1) {
array .push(arr[i])
}
}
return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}] //NaN、{}没有去重
- 四、利用sort(),根据排序后的结果进行遍历及相邻元素比对。
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return;
}
arr = arr.sort()
var arrry= [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i-1]) {
arrry.push(arr[i]);
}
}
return arrry;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
// [0, 1, 15, "NaN", NaN, NaN, {…}, {…}, "a", false, null, true, "true", undefined] //NaN、{}没有去重
- 五、利用includes()
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
var array =[];
for(var i = 0; i < arr.length; i++) {
if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
array.push(arr[i]);
}
}
return array
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}] //{}没有去重
- 六、利用reduce+includes
function unique(arr){
return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]
- 七、利用hasOwnProperty:判断是否存在对象属性
function unique(arr) {
var obj = {};
return arr.filter(function(item, index, arr){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}] //所有的都去重了
- 八、利用filter
function unique(arr) {
return arr.filter(function(item, index, arr) {
//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
return arr.indexOf(item, 0) === index;
});
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]
- 九、利用递归去重
function unique(arr) {
var array= arr;
var len = array.length;
array.sort(function(a,b){ //排序后更加方便去重
return a - b;
})
function loop(index){
if(index >= 1){
if(array[index] === array[index-1]){
array.splice(index,1);
}
loop(index - 1); //递归loop,然后数组去重
}
}
loop(len-1);
return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]
- 十、利用Map数据结构去重:创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。
function arrayNonRepeatfy(arr) {
let map = new Map();
let array = new Array(); // 数组用于返回结果
for (let i = 0; i < arr.length; i++) {
if(map .has(arr[i])) { // 如果有该key值
map .set(arr[i], true);
} else {
map .set(arr[i], false); // 如果没有该key值
array .push(arr[i]);
}
}
return array ;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]
22.字符串的test、match、search它们之间的区别?
`test`是检测字符串是否匹配某个正则,返回布尔值;
/[a-z]/.test(1); // false
`match`是返回检测字符匹配正则的数组结果集合,没有返回`null`;
'1AbC2d'.match(/[a-z]/ig); // ['A', 'b', 'C', 'd']
`search`是返回正则匹配到的下标,没有返回`-1`。
'1AbC2d'.search(/[a-z]/); // 2
23.字符串的slice、substring、substr它们之间的区别?
`slice`是返回字符串开始至结束下标减去开始下标个数的新字符串,下标是负数为倒数;
'abcdefg'.slice(2,3); // c // 3 - 2
'abcdefg'.slice(3,2); // '' // 2 - 3
'abcdefg'.slice(-2,-1); // f // -1 - -2
`substring`和`slice`正常截取字符串时相同,负数为0,且下标值小的为开始下标;
'abcdefg'.substring(2,3); //c // 3 - 2
'abcdefg'.substring(3,2); // c // 3 - 2
'abcdefg'.substring(3,-3); // abc // 3 - 0
`substr`返回开始下标开始加第二个参数(不能为负数)个数的新字符串。
'abcdefg'.substr(2, 3); // cde
'abcdefg'.substr(3, 2); // de
'abcdefg'.substr(-3, 2); // ef
24.Number('123')和new Number('123')有什么区别?
Number('123')是一个转换函数,会尝试把参数转为整数类型;而new Number('123')则不同,这是一个构造函数,它的结果是实例化出来一个对象。 同样的情况也适用用String和new String;Boolean和new Boolean的情况。
typeof Number('123') // number
typeof new Number('123') // object
25.==和===的区别?
===会判断两边变量的类型和值是否全部相等,==会存在变量类型转换的问题,所以并不推荐使用,只用一种情况会被使用,var == null是var === undefined || var === null的简写,其余情况一律使用===。
26.是否===就完全靠谱?
- 也是不一定的,例如0 === -0就为true,NaN === NaN为false,判断两个变量是否完全相等可以使用ES6新增的API,Object.is(0, -0),Object.is(NaN, NaN)就可以准确区分。
27.在类型转换中哪些值会被转为true?
- 除了undefined、null、false、NaN、''、0、-0以外的值都会被转为true,包括所有引用类型,即使是空的。
28.什么是基本包装类型?
- 基本类型:Undefined,Null,Boolean,Number,String
- 基本包装类型:Boolean,Number,String
- 在基本类型中,有三个比较特殊的存在就是:String Number Boolean,这三个基本类型都有自己对应的包装对象。包装对象,其实就是对象,有相应的属性和方法。调用方法的过程,是在后台偷偷发生的。
- 字符串、整数、布尔值,首先会使用各自的构造函数创建对应的实例,这样调用这些方法时就可以正常使用,不过再方法调用结束后,就会将实例给销毁掉,从而又是基本类型。
//我们平常写程序的过程:
var str = 'hello'; //string 基本类型
var s2 = str.charAt(0); //在执行到这一句的时候 后台会自动完成以下动作 :
(
var _str = new String('hello'); // 1 找到对应的包装对象类型,然后通过包装对象创建出一个和基本类型值相同的对象
var s2 = _str.chaAt(0); // 2 然后这个对象就可以调用包装对象下的方法,并且返回结给s2.
_str = null; // 3 之后这个临时创建的对象就被销毁了, str =null;
)
alert(s2);//h
alert(str);//hello
29.toString()和valueOf的区别?
- null和undefined没有以上两个方法。
- toString:值类型时返回自身的字符串形式;当是引用类型时,无论是一维或多维数组,将他们拍平成一个字符串,里面的null和undefined转为空字符串'',对象转为[object Object],函数的原样返回字符串形式。
- valueOf无论是值类型还是引用类型,大部分情况下都是原样返回,当是Date类型时,返回时间戳。
- 在进行字符串强转的时候,toString会优先于valueOf;在进行数值运算时,valueOf会优先于toString。
- 当执行toString的变量是一个整数类型时,支持传参,表示需要转为多少进制的字符串。
- www.cnblogs.com/chorkiu/p/1…
30.谈谈对this的理解?
调用的上下文环境包括全局和局部。
- 全局环境:在script标签里面,这里的this始终指向的是window对象。
<script>
console.log(<strong>this</strong>);//指向window对象
</script>
- 局部环境
- 1)在全局作用域下直接调用函数,this指向window
function func(){
console.log(this) ;//this指向的还是window对象
}
func()
- 2)对象函数调用,哪个对象调用就指向哪个对象
<input type="button"id="btnOK" value="OK">
<script>
varbtnOK=document.getElementById("btnOK");
btnOK.οnclick=function(){
console.log(this);//this指向的是btnOK对象
}
</script>
- 3)使用 new 实例化对象,在构造函数中的this指向实例化对象。
var Show=function(){
this.myName="Mr.Cao"; //这里的this指向的是obj对象
}
var obj=new Show();
4)使用call或apply改变this的指向
var Go=function(){
this.address="深圳";
}
var Show=function(){
console.log(this.address);//输出 深圳
}
var go=new Go();
Show.call(go);//改变Show方法的this指向go对象
- 加分项
1. 用于区分全局变量和局部变量,需要使用this
var age=20;
function show(age){
this.age=age;
}
2.返回函数当前的对象
live: function( types, data, fn ) {
jQuery( this.context ).on( types, this.selector, data, fn );
return this;
}
3.将当前的对象传递到下一个函数
each: function( callback, args ) {
return jQuery.each( this, callback, args );
}
31.改变当前调用this的方式?
- call:会立即执行调用call方法的函数,不过是以第一个参数为this的情况下调用,方法内可以传递不等的参数,作为调用call方法的参数。
- apply:运行方式和call是一致的,只是接受的参数不同,不能是不定参数,得是一个数组。
- bind:会改变当前的this,接受不定参数,不过不会马上执行调用bind方法的函数,而是返回一个函数作为结果,执行后才是调用函数的结果