2019春招笔试

本文详细介绍了前端开发中的关键概念和技术,包括盒子模型、样式优先级、JS深度克隆等,并探讨了前端性能优化策略、水平垂直居中技巧、清除浮动的方法及跨域解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

盒子模型

样式优先级

JS深度克隆

前端性能优化

水平垂直居中

经典的Foo和getName

JS中的this

清除浮动的方法

跨域

TCP与UDP

设计模式

多态

重载和重写

原型链

快速查询

闭包

冒泡查询

xml和json的区别

时间复杂度

 


 

 

盒子模型

什么是盒子模型?盒子模型分为哪几种?它们分别有什么特点?

1.内容content+内边距padding+边框border+外边距margin

2.IE盒模型border-box和普通盒模型content-box

3.content-box 的width=content;border-box的width=content+padding+border

 

样式优先级

1.内联式 > 嵌入式 > 外部式

2.内联样式  > id选择器样式 > 类选择器样式 > 元素选择器样式

3.!important与以上的选择器相遇时,强制使用此样式

 

深拷贝和浅拷贝

【参考文章:https://www.cnblogs.com/echolun/p/7889848.html

function deepClone(obj){
    let _obj = JSON.stringify(obj),
        objClone = JSON.parse(_obj);
    return objClone
}    
let a=[0,1,[2,3],4],
    b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

利用JSON对象的parse和stringify可以代替下面的深度克隆函数里的代码

 

JS深度克隆

定义一个函数,让对象深度克隆。

【参考文章:https://www.jianshu.com/p/2a3728cded4c?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

需要实现一个对象类型判断函数

const isType = (obj, type) => {
  if (typeof obj !== 'object') return false;
  // 判断数据类型的经典方法:
  const typeString = Object.prototype.toString.call(obj);
  let flag;
  switch (type) {
    case 'Array':
      flag = typeString === '[object Array]';
      break;
    case 'Date':
      flag = typeString === '[object Date]';
      break;
    case 'RegExp':
      flag = typeString === '[object RegExp]';
      break;
    default:
      flag = false;
  }
  return flag;
};

深度克隆函数

const clone = parent => {
  // 维护两个储存循环引用的数组
  const parents = [];
  const children = [];

  const _clone = parent => {
    if (parent === null) return null;
    if (typeof parent !== 'object') return parent;

    let child, proto;

    if (isType(parent, 'Array')) {
      // 对数组做特殊处理
      child = [];
    } else if (isType(parent, 'RegExp')) {
      // 对正则对象做特殊处理
      child = new RegExp(parent.source, getRegExp(parent));
      if (parent.lastIndex) child.lastIndex = parent.lastIndex;
    } else if (isType(parent, 'Date')) {
      // 对Date对象做特殊处理
      child = new Date(parent.getTime());
    } else {
      // 处理对象原型
      proto = Object.getPrototypeOf(parent);
      // 利用Object.create切断原型链
      child = Object.create(proto);
    }

    // 处理循环引用
    const index = parents.indexOf(parent);

    if (index != -1) {
      // 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象
      return children[index];
    }
    parents.push(parent);
    children.push(child);

    for (let i in parent) {
      // 递归
      child[i] = _clone(parent[i]);
    }

    return child;
  };
  return _clone(parent);
};

 

前端性能优化

前端性能优化的方案有哪些?

减少HTTP请求、使用CDN、添加Expires头、压缩组件、将样式表放在头部、将脚本放在底部、避免CSS表达式、使用外部的JavaScript和CSS、减少DNS查找、精简JavaScript、避免重定向、删除重复脚本、配置ETag、使Ajax可缓存。

 

 

水平垂直居中

使未知宽高的child子元素在father父元素中水平垂直居中的方法有哪些?

1.显示设置父元素为:table,子元素为:table-cell,这样就可以使用vertical-align: middle,text-align: center

2.使用一个空标签span设置他的vertical-align基准线为中间,并且让它为inline-block,宽度为0

3.父元素position非static,子元素绝对定位,top 50%,left50%,然后使用css3 transform:translate(-50%; -50%)

4.使用css3 flex布局:父元素display:flex; 子元素margin:auto;

 

 

<li>标签

li与li之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

<li>标签设置为display:inline-block时,会出现看不见的空白间隔。

引起这种空白间隔的原因:

浏览器的默认行为是把inline元素间的空白字符(空格换行tab)渲染成一个空格,也就是我们上面的代码<li>换行后会产生换行字符,而它会变成一个空格,当然空格就占用一个字符的宽度。

解决方案:

1.既然是因为<li>换行导致的,那就可以将<li>代码全部写在一排;

2.<ul>内的字符尺寸直接设为0

3.在Safari浏览器方法2依然出现间隔空白,所以设置.wrap ul{letter-spacing: -5px;},然后设置li内字符间隔.wrap ul li{letter-spacing: normal;}
 

 

经典的Foo和getName

【参考文章:https://www.cnblogs.com/laojun/p/8287399.html

 

 

JS中的this

function a(xx){
    this.x=xx;
    return this
};
var x=a(5);
var y=a(6);
//写出以下代码的输出结果
console.log(x.x);
console.log(y.x);

答案是undefined 6

原因:【参考文章:https://segmentfault.com/q/1010000018487598

1.在全局环境中使用var x,相当于给window添加x属性
2.执行var x = a(5),在function中给x赋值为5,但是将this返回给它本身,则导致它又等于window,此时x === x.x === x.x.x === ... === window,按照理论来说只要你能输出所有的x.x,那应该能有机会看到5,但这本身是一个无限循环
3.至于y为何没有undefined,原因是它没有和x变量同名

 

 

清除浮动的方法

【参考文章:https://www.cnblogs.com/nxl0908/p/7245460.html 】

 

 

跨域

1、什么是同域?是指域名相同,端口相同,协议相同。

2、什么是同源策略?
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。

不受同源策略限制的:
1、页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
2、跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。

3、什么是跨域?是指一个域下的文档或脚本试图去请求另一个域下的资源。

4、跨域方法?

1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

 

 

TCP与UDP

tcp和udp的区别?

1.tcp面向连接;udp无连接。

2.tcp提供可靠的服务;udp尽最大努力交付,不保证可靠交付。

3.udp具有较好的实时性,工作效率比tcp高。

4.tcp连接是点对点;udp可支持一对一、一对多、多对一的交互通信。

5.tcp对系统资源要求较多,udp较少。

tcp是如何确保可靠性的?

tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。

 

设计模式

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

简单工厂模式:定义一个用于创建对象的接口。

工厂方法模式:是简单工厂模式的衍生,解决了许多简单工厂模式的问题。

抽象工厂模式:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

 

 

多态

定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。

多态存在的三个必要条件:1.要有继承;2.要有重写;3.父类引用指向子类对象。

 

 

重载和重写

重载:重载字面意思多次的意思,也就是同一个方法实现多个不同的逻辑,并可以在同一个类中可以实现。其实现的原理是,方法名相同,参数的个数或者类型不同即可。

重写:重写就是要重新去写(实现),一个类中不可能两个定义一样的方法。因此,重写就是子类对父类定义的方法重新实现一次。

 

 

闭包

闭包就是定义在函数中的函数。

闭包的两大作用:一个是读取函数中的变量,另外一个是将函数中的变量的值存储于内存中。

闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

 

 

JS的数据类型

【参考文章: https://www.cnblogs.com/starof/p/6368048.html

 

 

原型链

原型链

【参考文章: https://www.jianshu.com/p/dee9f8b14771

var o1 = {}; 
var o2 =new Object();
var o3 = new f1();

function f1(){}; 
var f2 = function(){};
var f3 = new Function('str','console.log(str)');

console.log(typeof Object); //function 
console.log(typeof Function); //function  

console.log(typeof f1); //function 
console.log(typeof f2); //function 
console.log(typeof f3); //function   

console.log(typeof o1); //object 
console.log(typeof o2); //object 
console.log(typeof o3); //object

【参考文章: https://blog.youkuaiyun.com/u010365819/article/details/81326349

第一题:person1.__proto__ 是什么?
因为 person1.__proto__ === person1 的构造函数.prototype
因为 person1的构造函数 === Person
所以 person1.__proto__ === Person.prototype

第二题:Person.__proto__ 是什么?
因为 Person.__proto__ === Person的构造函数.prototype
因为 Person的构造函数 === Function
所以 Person.__proto__ === Function.prototype

第三题:Person.prototype.__proto__ 是什么?
Person.prototype 是一个普通对象,我们无需关注它有哪些属性,只要记住它是一个普通对象。
因为一个普通对象的构造函数 === Object
所以 Person.prototype.__proto__ === Object.prototype

第四题:Object.__proto__ 是什么?                                                                                                                                        参照第二题,因为 Person 和 Object 一样都是构造函数

第五题:Object.prototype__proto__ 是什么?
Object.prototype 对象也有proto属性,但它比较特殊,为 null 。因为 null 处于原型链的顶端,这个只能记住。
Object.prototype.__proto__ === null

 

 

快速排序

【参考文章:https://blog.youkuaiyun.com/adusts/article/details/80882649

 

冒泡排序

 

 

xml和json的区别

【参考文章:https://www.cnblogs.com/SanMaoSpace/p/3139186.html

 

 

时间复杂度

 

 

数据结构

数据结构有哪些?

数组、栈、队列、链表、树、图、堆、散列表。

 

 

==和===的区别

==用于一般比较,===用于严格比较,==在比较的时候可以转换数据类型,===严格比较,只要类型不匹配就返回flase。
举例说明:

"1" == true类型不同,"=="将先做类型转换,把true转换为1,即为 "1" == 1;此时,类型仍不同,继续进行类型转换,把"1"转换为1,即为 1 == 1。

1.如果比较:"1" === true 左侧为字符型,右侧为bool布尔型或int数值型,左右两侧类型不同,结果为false;

2.如果比较: 1 === 1 左侧为int数值型,右侧为int数值型,左右两侧类型相同,数值大小也相同,结果为true;

3.如果比较: 1 === 2 左侧为int数值型,右侧为int数值型,左右两侧类型相同,但数值大小不同,结果为false。

 

 

typeOf和instanceOf的区别

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值