css和js面试题

(一) css面试

1.盒子水平垂直居中

(五大方案)

  • 定位:三种

    • 前提:父盒子相对定位,子盒绝对定位
    • [1]. 父盒子有固定宽高,在子样式中写出计算出的子盒子应该距离顶部和左边的距离
    • [2]. 父盒子有固定宽高
      .son{
              
              
      	position:absolute;
      	top:0;
      	left:0;
      	right:0;
      	bottom:0;
      	margin: auto;
      }
      
    • [3]. 问题:存在不兼容
      position:absolute;
      top:50%;
      left: 50%;
      transform: translate(-50%,-50%);
      
  • display:flex 问题:不兼容

    .father{
          
          
    	display: flex;
        justify-content: center;
        align-items: center;
    }
    
  • javascript 算出来

  • 使用table-cell (原本是控制文本的,所以可以将子盒子设置为inline-block)

    .father{
          
          
    	//需要有固定的宽高
    	//宽高不能是百分比
    	display:table-cell;
    	vertical-align:middle;
    	text-align:center;
    }
    

2.css3盒模型

  • 标准盒模型(box-sizing:content-box)、怪异盒模型(ie盒模型)和flex弹性伸缩盒模型
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

3.几大经典布局方案

[1]. 圣杯布局

[2]. 双飞翼布局

4.移动响应式布局开发三大方案

  • media
  • rem
  • flex
  • vh / vw(类百分比)
  • 百分比

5.课后作业

  1. 使用css,让一个div在视野中消失

    1.position:absolute/relative/fixed  +  方位 top/bottom/left/right: -9999px
    2.display:none
    3.visibility:hidden
    4.width:0 + overflow:hidden
      height:0 +  overflow:hidden
    5.margin-top/bottom/left/right:-9999px;
    6.background-color:transparent
    7.opacity:0
    8.transform: translateX(-9999px)/translateY(-9999px)/translate(-9999px,-9999px)
    9.transform: scale(0)
    
  2. 请说明z-index的工作原理,适用范围
    https://www.kancloud.cn/fining/htmlcssknowledgepoints/1323032

    1.z-index这个属性控制着元素在z轴上的表现形式。
    2.适用范围:仅适用于定位元素,即拥有relative,absolute,fixed属性的position元素。
    3.堆叠顺序是当前元素位于z轴上的值,数值越大说明元素的堆叠1顺序越高,越靠近屏幕。
    4.未定义时,后来居上,未定义z-index的属性,元素的堆叠顺序基于它所在的文档树。默认情况下,后来的元素的z-index的值越大。
    5.使用范围:
    
    	1.网页两侧的浮动窗口(播放器,指定按钮,广告等)
    	2.导航栏浮动置顶
    	3.隐藏div实现弹窗功能(通过设置div定位和z-index控制div的位置和出现隐藏)
    
  3. 谈谈对html5的理解

优点:

1)多设备,跨平台;

2)用户体验好;

3)新标签的可读性高,有助于开发人员定义重要内容;

4)提供了更多的多媒体元素(视频和音频);

5)很好地替代了Flash和Silverlight;

6)涉及到网站的抓取和索引的时候,SEO更加友好;

7)可以被大量应用于移动应用程序和游戏。


缺点:

1)web storage和web socket这样的功能很容易被黑客利用,安全性差;

2)兼容性不好,很多浏览器的支持程度不一样;

3)有一定的技术门槛;

4)某些平台上的引擎问题导致HTML5性能低下;
  1. 如何使一个div里面的文字垂直居中,并且文字的大小根据屏幕大小自适应
    https://www.cnblogs.com/moqiutao/p/4807792.html#articleHeader1
    https://blog.csdn.net/liyede2008/article/details/78213054

  2. 下面哪个渲染性能高

.box a{
    
    
	...
}
a{
    
    
	...
}

(二) js面试

1.js的数据类型及区别

  1. 基础数据类型
    number string boolean null undefine
  2. 引用数据类型
    Object、symbol
    ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。
    object包含Data、function、Array等

2. 对象(数组)的深克隆和浅克隆

浅克隆

let obj = {
    
    
  a: 100,
    b: [10, 20, 30],
    c: {
    
    
        x: 10
    },
    d: /^\d+$/
};
function clone(obj){
    
    
   let obj2= {
    
    };
   for(let key in obj){
    
    
       //使用hasOwnProperty()方法来忽略继承属性。
       if(!obj.hasOwnProperty(key)) break;
       console.log(key);
       
       obj2[key] = obj[key]; 
   }
   return obj2
}
var obj2= clone(obj);
obj2.a = 200;//基础数据类型,不会影响被克隆的数值
obj2.b[0] = 200;//引用类型会影响被克隆的数值
console.log(obj2);
console.log(obj);

深克隆
可以使用JSON.stringify()来实现深克隆,但是JSON.stringify()处理函数,时间(new Date()),正则表达式时会出问题。

let obj = {
    
    
    a: 100,
    b: [10, 20, 30],
    c: {
    
    
        x: 10
    },
    d: /^\d+$/
};

function deepClone(obj) {
    
    
	if(obj === null) return null;
    if (typeof obj !== 'object') return obj;
    //  instanceof 测试一个对象是否为一个类的实例
    if(obj instanceof RegExp) return new RegExp(obj); //创建一个新实例,和原值引用不同的地址
    if(obj instanceof Date) return new Date(obj);
    //不直接创建空对象的目的:克隆的结果和obj保持相同的所属类
    //比如:如果obj是一个实例,则new obj.constructor相当于new obj所属的类。
    let cloneObj = new obj.constructor;
    for(let key in obj){
    
    
        if(obj.hasOwnProperty(key)){
    
    
            cloneObj[key] = deepClone(obj[key]);
        }
    }
    return cloneObj;
}
var obj2= deepClone(obj);
obj2.a = 200;
obj2.b[0] = 200;
console.log(obj2);
console.log(obj)

3.堆栈内存

//example 1
//字符串属性名和数字属性名相同时表示的是一个属性名
 let a = {
    
    }, b = '0', c = 0;
 a[b] = '珠峰';
 a[c] = '培訓';
 console.log(b);
 console.log(a[b]);
 //example 2
 //Symbol创建唯一值,即b !== c
 let a = {
    
    }, b = Symbol('1'), c = Symbol('1');
 a[b] = '珠峰'; 
 a[c] = '培訓';
 console.log(b);
 console.log(c);
 console.log(a[b]);
 //example 3
 //对象存储引用类型值最后都会变为字符串进行存储
 //在存储b对象时,会进行b.toString()操作,变为[objct, objct],存储c时也会进行toString()操作,变为[objct, objct],所以‘培训’会将‘珠峰’给覆盖掉
 let a = {
    
    } b = {
    
    n:'1'}, c = {
    
    m:'2'};
 a[b] = '珠峰';
 a[c] = '培訓';
 console.log(b);
 console.log(a[b]);

第一道题:
在这里插入图片描述
数组和对象的区别

  • 数组表示有序数据的集合,而对象表示无序数据的集合。如果数据的顺序很重要,就用数组,否则就用对象。
    数组和对象的另一个区别是,数组的数据没有”名称”(name),对象的数据有”名称”(name)。

4.闭包

返回字符串4

var test = (function(i){
    
    
    return function(){
    
    
    	//alert弹出来的都是字符串
        alert(i*2);
    }
})(2);
test(5);

5.闭包2

var a = 0, b = 0;
function A(a){
    
    
    A = function(b){
    
    
        alert(a+b++);
    }
    alert(a++)
}
A(1);
A(2);

在这里插入图片描述

6.变量提升

变量提升就是(var和function声明的时代下)在当前作用域下,所有代码执行之前,把所有带var和function关键字提前声明和定义,带var的变量提前声明,带function的变量提前声明和定义

function Foo() {
    
    
   getName = function () {
    
    
        console.log(1);
    };
    return this;
}
Foo.getName = function () {
    
    
    console.log(2);
}
Foo.prototype.getName = function () {
    
    
    console.log(3);
}
var getName = function () {
    
    
    console.log(4);
}

function getName() {
    
    
    console.log(5);
}
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3
  1. 同步异步
async function async1(){
    
    
  	console.log('async1 start');//2
    await async2();
    console.log('async1 end');//6
}

async function async2(){
    
    
    console.log('async2');//3
}

console.log('script start');  //1

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

async1();

new Promise(function(resolve){
    
    
    console.log('promise1');//4
    resolve();
}).then(function(){
    
    
    console.log('promise2');//7
});

console.log('script end');//5

在这里插入图片描述

7.call 和apply的区别是什么,哪个性能更好一些

bind的this指向不会立即执行
call 和apply都是function原型上的方法,每一个函数都是function原型上的实例,可以调用原型上的call和apply,call和apply都是改变函数中的this指向,唯一的区别就是call是一个个传递参数,apply是传递一个数组
fn.call(obj, 10,20,30)
fn.apply(obj, [10,20,30])
参数超过三个,call比apply性能高一点。
后期开发的时候,可以使用call多点

//测试代码执行时间
console.time('A');
//代码
console.timeEnd('A');

8.实现(5).add(3).minus(2),使其结果为6

~ function () {
    
    
	  function check(n) {
    
    
	      //将传递进来的n转换为数字,如果是一个非有效数字  n==NaN
	      n = Number(n);
	      return isNaN(n) ? 0 : n;
	  }
	
	  function add(n) {
    
    
	      n = check(n)
	      return this + n;
	  }
	
	  function minus(n) {
    
    
	      n = check(n)
	      return this - n;
	  }
	  Number.prototype.add = add;
	  Number.prototype.minus = minus;
}();//这里的分号要写
console.log( (5).add(3).minus(2));

9. 给英文单词前后加空格

let str = 'no作no死,you can you 上',
  reg = /\b\w+\b/ig;
as = str.replace(reg, function (value) {
    
    
    return ' ' + value + ' ';
}).trim();
console.log(as);

10. 箭头函数与普通函数(function)的区别是什么?构造函数(function)可以使用new生成实例,那么箭头函数可以吗?为什么?

  • 区别:
    1.箭头函数语法上比普通函数更加简洁
    funtion fn(x){
          
          
    	return function(y){
          
          
    		return x + y
    	}
    }
    let fn = x=> y => x + y;
    
    2.箭头函数没有自己的this,它里面出现的this从属于函数所处的上下文中的this(使用call/apply等任何方式都无法改变this的指向)
    let obj = {
          
          
    	name:'obj'
    }
    function fn1(){
          
          
    	console.log(this);
    }
    fn1.call(obj);
    let fn2 = ()=>{
          
          
    	console.log(this)
    }
    fn2.call(obj)
    

3.this的指向

//箭头函数外边没有其他函数包围,一般指向window(自己想的)
document.body.onclick = ()=>{
    
    
	//=>this为window 而不是body
}
document.body.onclick = function (){
    
    
	//=>this为body
	arr.sort(function (a,b){
    
    
		//this为window,而不是arr或者sort,因为sort只是执行了当前函数,回调函数中的this,一般指向window
	})
}
  1. 箭头函数中没有arguments,
  2. 箭头函数不能被new(因为箭头函数没有this也没有prototype)

11. 字符串大小写取反,例如‘AbC’变为‘aBc’

let str = "asdfSDNSFNdsfafas;找房"
//content是匹配到的字符
str = str.replace(/[a-zA-Z]/g, content=>{
    
    
    //str.charCodeAt() 获取字符的ASCII码
   return  content.toUpperCase() === content ? content.toLowerCase() : content.toUpperCase();
})
console.log(str);

12. 在一个字符串中查到另一个方法,返回其位置,不存在返回-1,不能用indexof

let str1 = 'wangwendong';
let str2 = 'wen';
console.log(str1.indexOf(str2));

String.prototype.myIndexOf = function myIndexOf(str2) {
    
    
//this就是str1
console.log(this);
let str1Length = this.length;
let str2Length = str2.length;
if(str1Length< str2Length){
    
    
   return -1;
}
for (let i = 0; i <= str1Length - str2Length; i++){
    
    
    let empstr = this.substr(i,str2Length);
    if(empstr === str2){
    
    
        return i;
    }
}
return -1;
    
}
console.log(str1.myIndexOf(str2));
//z正则
 String.prototype.myIndexOf2 = function (str2){
    
    
     let reg = new RegExp(str2);
     let res = reg.exec(this);
     return res === null ? -1 : res.index;
 }
 console.log(str1.myIndexOf(str2));

12. 引用变量

//对象中数字属性名123和字符串属性名'123'表示的是同一个
//即a[123] == a['123']
 var a={
    
    }, b='123',c=123;
a[b] = 'b';
a[c] = 'c'
console.log(a[b]);
//Symbol创建的值是唯一的
var a = {
    
    }, b = Symbol('123'), c=Symbol('123');
a[b] = 'b';
a[c] = 'c';
console.log(a[b]);
//对象的属性名不能是引用类型,会自动将引用类型变为字符串类型
//({key:'123'}).toString() 转换为字符串 '[Object,Object]',
//[1,2,3].toString()转换为字符串 '1,2,3'
var a ={
    
    }, b = {
    
    key:'123'}, c={
    
    key:'456'}
a[b] = 'b';
a[c] = 'c';
console.log(a[b]);

13. 验证url

let url = 'https://www.baidu.com:80/index.html?name=zhang&age=12#search';
let reg = /^((http|https|ftp):\/\/)?([\w-]+\.)+([a-z0-9])+(:(\d)+)?((\/[^/?#]*)+)?(\?[^?#]+)?(#.+)?$/i;
 console.log(reg.exec(url));

14. 函数的三种角色

function Foo(){
    
    
   Foo.a = function(){
    
    
        console.log(1);
    }
    this.a = function (){
    
    
        console.log(2);
    }
}
//讲Foo当做类,在原型上设置实例共有的属性方法 调用:实例.a()
Foo.prototype.a = function(){
    
    
    console.log(3);
    
}
//将Foo当做普通对象设置私有的属性方法   调用:Foo.a()
Foo.a = function (){
    
    
    console.log(4);
}
Foo.a();//4  调用它的时候,没有调用构造函数Foo
let obj = new Foo();//调用了构造函数Foo,foo.a 输出1
obj.a();//2
Foo.a();

15. 图片懒加载

  1. 前端性能优化的重要方案
    1). 通过图片的延时或者数据的延迟加载,我们可以加快页面的渲染速度,让第一次打开页面的速度变快
    2). 只有滑动到某个区域,我们才加载真实的图片,这样也可以节省加载的流量
  2. 处理方案
    1). 所有需要延迟加载的图片用一个盒子包起来,设置宽高和默认占位图
    2). 开始让所有的src为空,把真实图片的地址放到img的自定义属性上,让img隐藏等到所有其他资源都加载完成后,我们再开始加载图片
    3). 对于很多图片,需要当页面滚动的时候,当前图片区域完全显示出来后再加载真实图片
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片延迟加载</title>
    <style>
        * {
     
     
            padding: 0;
            margin: 0;
        }

        .container {
     
     
            width: 100%;
        }

        .img_box {
     
     
            width: 215px;
            height: 215px;
            background-color: gray;
            margin: 0 auto 10px;
        }

        .img_box img {
     
     
            width: 100%;
            display: none;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="img_box">
            <img src="" alt="" data-link="https://cn.vuejs.org/images/logo.png">
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
        let $window = $(window);
        let $container = $(".container");
        //创建20个img_box
        let str = '';
        new Array(20).fill(null).forEach((item, index) => {
     
     
            str +=
                '<div class="img_box"><img src="" alt="" data-link="https://cn.vuejs.org/images/logo.png"></div>';
        });
        $container.html(str);



        let $imgBoxArr = $(".img_box");

        $window.on('load scroll', function () {
     
     
            $imgBoxArr.each((index, item) => {
     
     

                let $item = $(item);
                if ($item.attr('data-load') === 'true') return;
                //图片距离顶部的距离
                let $imgPosition = $item.offset().top + $item.outerHeight();
                let $srceenPosition = $window.outerHeight() + $window.scrollTop();

                if ($imgPosition < $srceenPosition) {
     
     
                    let $img = $item.children();

                    $img.attr('src', $img.attr('data-link'));
                    $img.on('load', function () {
     
     
                        //$img.css('display', 'block')
                        $img.stop().fadeIn();
                        //data-load设置的值为字符串true
                        $img.parent().attr('data-load', true)
                    })
                }
            })
        })
    </script>
</body>

</html>

15. 正向预查

(?=pattern)正向预查:/cainiao(?=8)/ 只能匹配cainiao8中的cainiao,而不能匹配cainiao9中的cainiao,也不能匹配cainiao
(?!pattern)负向预查:必须不满足pattern这个条件。/cainiao(?!8)/能匹配cainiao

一个6~16位的字符串,必须同时包含有大小写字母和数字

//(?!^[a-zA-Z]+$)  非小写字母,非大写字母,非大小写字母混合
//(?!^[0-9a-z]+$) 非小写字母,非数字,非大小写字母混合

console.log(/(?!^[a-zA-Z]+$)(?!^[0-9A-Z]+$)(?!^[0-9a-z]+$)^[0-9a-zA-Z]{6,16}$/.test('123Asad'));

16. 根据属性名和属性值返回元素

写一个方法,输入属性名和属性值返回返回所有符合的元素

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div class="box con"></div>
    <div class="time" id="box"></div>
    <div class="conbox"></div>
    <div class="t"></div>
    <div data-src="baidu"></div>
    <div class="box"></div>
    <script>
        function $attr(attr, value) {
     
     
            //获取所有子节点,得到object
            //let children =document.body.children;
            let children = document.getElementsByTagName('*')
            let arr = [];
            //将object转换为数组
            children = Array.from(children);

            children.forEach(item => {
     
     
                //获取属性值
                let itemValue = item.getAttribute(attr);

                if (itemValue === value) {
     
     
                    arr.push(item);
                }else if(attr === 'class'){
     
     //判断class 为 box  con的情况
                    new RegExp('\\b'+value+'\\b').test(itemValue) ? arr.push(item) : '';
                }
            });
            return arr;
        }
       console.log(  $attr('class', 'box'));
      
    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/kouzuhuai2956/article/details/107043424