zoukankan      html  css  js  c++  java
  • 前端面试题四

    1. js原型链

    2. 服务器端怎么设置cookie?

    expires

    该属性用来设置Cookie的有效期。Cookie中的maxAge用来表示该属性,单位为秒。Cookie中通过getMaxAge()和setMaxAge(int maxAge)来读写该属性。

    cookie.setMaxAge(0);//不记录cookie

    cookie.setMaxAge(-1);//会话级cookie,关闭浏览器失效

    cookie.setMaxAge(60*60);//过期时间为1小时

    3. Javascript数据类型,Symbol类型一般怎样使用,引用类型和基本类型

    基本数据类型:String、Number、null、undefined、Boolean、Symbol、BigInt

    应用场景一:我们可以将Symbol用来作为对象属性名(key)

    Symbol类型的key是不能通过object.keys()或者for...in来枚举的,它未被包含在对象自身的属性名集合(property names)之中。多以利用该特性,我们可以把一些不需要对外操作或者访问的属性使用Symbol来定义。

    也正因为这样的一个特性,我们在使用JSON.stringify()将对象,JSON字符串的时候,Symbol属性你也会排除在输出内容之外。

    我们可以利用这一特点来更好的设计我们的数据对象,让“对内操作”和“对外选择性输出”变得更加优雅。

    有一些专门的API还是可以取得到Symbol定义的属性的:

    然而,这样的话,我们就没办法获取以Symbol方式定义的对象属性了么?非也。还是会有一些专门针对Symbol的API,比如:
    
    // 使用Object的API
    Object.getOwnPropertySymbols(obj) // [Symbol(name)]
    
    // 使用新增的反射API
    Reflect.ownKeys(obj) // [Symbol(name), 'age', 'title']
    

    应用场景二:使用Symbol来代替常量

    const TYPE_AUDIO = 'AUDIO'
    const TYPE_VIDEO = 'VIDEO'
    const TYPE_IMAGE = 'IMAGE'
    

    使用Symbol之后

    const TYPE_AUDIO = Symbol()
    const TYPE_VIDEO = Symbol()
    const TYPE_IMAGE = Symbol()
    

    应用场景三:使用Symbol来定义类的私有属性/方法

    JS中没有Java的private

    而有了Symbol以及模块化机制,类的私有属性和方法菜变得可能。

    在文件a.js中

    const PASSWORD = Symbol()
    
    class Login {
      constructor(username, password) {
        this.username = username
        this[PASSWORD] = password
      }
    
      checkPassword(pwd) {
          return this[PASSWORD] === pwd
      }
    }
    
    export default Login
    

    在文件b.js中

    import Login from './a'
    
    const login = new Login('admin', '123456')
    
    login.checkPassword('123456')  // true
    
    login.PASSWORD  // oh!no!
    login[PASSWORD] // oh!no!
    login["PASSWORD"] // oh!no!
    

    由于Symbol常量PASSWORD被定义在a.js所在的模块中,外面的模块获取不到这个Symbol,也不可能再创建一个一模一样的Symbol出来(因为Symbol是唯一的),因此这个PASSWORD的Symbol只能被限制在a.js内部使用,所以使用它来定义的类属性是没有办法被模块外访问到的,达到了一个私有化的效果。

    基本类型:string,number,boolean,null,undefined,symbol、bigint

    引用类型:Function,Array,Object

    4. 手写数组去重

    利用indexOf去重

    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;
    }
    

    利用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)
        })
    }
    

    5. 讲一下事件流?

    (1)事件流描述的是从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。
    (2)事件就是用户或浏览器自身执行的某种动作。诸如click(点击)、load(加载)、mouseover(鼠标悬停)。
    (3)事件处理程序响应某个事件的函数就叫事件处理程序(或事件侦听器)。

    dom2级事件规定的事件包括三个阶段:事件捕获阶段==>处于目标阶段==>事件冒泡阶段 

    洋葱模型

    6. preventDefault()和stopPropagation()的区别

    stopPropagation()阻止事件冒泡

    preventDefault()阻止事件默认行为

    该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作)。例如,如果 type 属性是 "submit",在事件传播的任意阶段可以调用任意的事件句柄,通过调用该方法,可以阻止提交表单。注意,如果 Event 对象的 cancelable 属性是 fasle,那么就没有默认动作,或者不能阻止默认动作。无论哪种情况,调用该方法都没有作用。

    7. 解决异步的几种方式?
    (1)回调函数

    function f1(f2){
        setTimeout(function(){
            console.log('先执行 f1')
        },1000)
        f2()
    }
    function f2() {
        console.log('再执行 f2')
    }
    

    总结:回调函数易于实现,便于理解,但多次回调会使得代码高度耦合,回调地狱。

    (2)事件监听

    脚本的执行不取决代码的顺序,而取决于某一个事件是否发生。

    $(document).ready(function(){
         console.log('DOM 已经 ready')
    });
    

      

    (3)发布订阅模式

    发布/订阅模式是利用一个消息中心,发布者发布一个消息给消息中心,订阅者从消息中心订阅该消息,。类似于 vue 的父子组件之间的传值。

    //订阅done事件
    $('#app').on('done',function(data){
        console.log(data)
    })
    //发布事件
    $('#app').trigger('done,'haha')

    (4)promise

    Promise 实际就是一个对象, 从它可以获得异步操作的消息,Promise 对象有三种状态,pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise 的状态一旦改变之后,就不会在发生任何变化,将回调函数变成了链式调用。

    export default function getMethods (url){
        return new Promise(function(resolve, reject){
            axios.get(url).then(res => {
                resolve(res)
            }).catch(err =>{
                reject(err)
            })
        })
    }
    
    getMethods('/api/xxx').then(res => {
        console.log(res)
    }, err => {
        console.log(err)
    })
    

      

    (5)generator

    Generator 函数是一个状态机,封装了多个内部状态。执行 Generator 函数会返回一个遍历器对象,使用该对象的 next() 方法,可以遍历 Generator 函数内部的每一个状态,直到 return 语句。

    形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式, yield是暂停执行的标记。

    next() 方法遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

    function *generatorDemo() {
      yield 'hello';
      yield  1 + 2;
      return 'ok';
    }
    
    var demo = generatorDemo()
    
    demo.next()   // { value: 'hello', done: false } 
    demo.next()   // { value: 3, done: false } 
    demo.next()   // { value: 'ok', done: ture } 
    demo.next()   // { value: undefined, done: ture } 
    

      

    (6)async/await

    async函数返回的是一个 Promise 对象,可以使用 then 方法添加回调函数,async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

    await命令后面返回的是 Promise 对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。

    async function demo() {
      try {
        await new Promise(function (resolve, reject) {
          // something
        });
      } catch (err) {
        console.log(err);
      }
    }
    
    demo().then(data => {
        console.log(data)  // 
    })
    

      

    8. defer和async的区别

    (1)<script src="script.js"></script>

      没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素读到就加载并执行。

    (2)<script async src="script.js"></script>

      有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。

    (3)<script defer src="myscript.js"></script>

      有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

     9. 写一下双飞翼布局,两边固定中间自适应

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>双飞翼布局</title>
    </head>
    <style>
      body{
        margin: 0;
        padding: 0;
      }
      #wrapper{
        min- 600px;
      }
      #header,#footer{
        100%;
        height: 50px;
        line-height: 50px;
        background: yellow;
      }
      #content{
        /*  100%; */
        overflow: hidden;
      }
      #left,#right,#middle{
        float:left;
        height: 500px;
      }
      #left{
        margin-left: -100%;
         160px;
        background: orange;
      }
      #middle{
         100%;
        background: pink;
      }
      #right{
        margin-left: -200px;
         200px;
        background: blue;
      }
      #middle-content{
        margin: 0 200px 0 160px;
      }
      
    </style>
    <body>
      <div id="wrapper">
        <div id="header">header</div>
        <div id="content">
          <div id="middle">
            <div id="middle-content">middle</div>
          </div>
          <div id="left">left</div>
          <div id="right">right</div>
        </div>
        <div id="footer">footer</div>
      </div>
    </body>
    </html>
    

    10. 移动端适配方式

    (1)百分比方案

    使用百分比%宽度,高度用px固定,根据可视化区域实时尺寸进行调整,尽可能适应各种分辨率,通常使用max-width/min-width控制尺寸范围过大或者过小。下表是子元素不同属性设置百分比的依据。

    优势:原理简单,不存在兼容问题

    不足:

    • 如果屏幕尺度跨度太大,相对设计稿过大或者过小的屏幕不能正常显示,在大屏手机或横竖屏切换场景下可能会导致页面元素被拉伸变形,字体大小无法随屏幕大小发生变化。
      ...
    • 设置盒模型的不同属性时,其百分比设置的参考元素不唯一,容易使布局问题变得复杂

    (2)rem方案

    rem是相对长度单位,rem方案中的样式设计相对于根元素font-size计算值得倍数。

    根据屏幕宽度设置html标签的font-size,在布局时使用rem单位布局,达到自适应的目的,是弹性布局的一种实现方式。

    • 兼容性好

    不足:不是纯css移动适配方案,需要引入js脚本 在头部内嵌一段 js脚本 监听分辨率的变化来动态改变根元素的字体大小,css样式和 js 代码有一定 耦合性,并且必须将改变font-size的代码放在 css 样式之前。

    (3)vh/vw方案

    视口是浏览器中用于呈现网页的区域,移动端的视口通常指的是 布局视口

    • vw : 1vw 等于 视口宽度1%
    • vh : 1vh 等于 视口高度 的 **1% **
    • vmin : 选取 vwvh最小 的那个
    • vmax : 选取 vwvh最大 的那个

    优势:纯 css 移动端适配方案,不存在脚本依赖问题

    不足:存在一些兼容性问题,Android4.4以下不支持

     

    (4)rem+vw/vh方案

    vw/vh 方案能够实现宽度和高度的自适应,并且逻辑清晰,由于其被支持得较晚,所以存在一定的兼容性问题。将 vw/vh 方案与 rem 方案相结合,给根元素设置随视口变化的vw单位,可以通过postcss-plugin-vwtorem将其转换。具体的计算过程为:

    对于1080px宽的设计稿,设置默认根字号的大小为100px,那么设计稿中1px对应的是 100vw/1080 = 0.0925926vw,并且 1rem = 100px,也就可以得到1rem = 9.256926vw

    同时可以使用媒体查询限制根元素的最大最小值,实现对页面的最大最小宽度限制,对用户的视觉体验更好。

    (5)基于媒体查询的响应式设计

    响应式设计 使得一个网站同时适配 多种设备 和 多个屏幕,让网站的布局和功能随用户的使用环境(屏幕大小、输出方式、设备/浏览器能力而变化),使其视觉合理,交互方式符合习惯。如使得内容区块可伸缩与自由排布,边距适应页面尺寸,图片适应比例变化,能够自动隐藏/部分显示内容,能自动折叠导航和菜单。
    原理:主要实现是通过 媒体查询,通过给不同分辨率的设备编写不同的样式实现响应式布局,用于解决不同设备不同分辨率之间兼容问题,一般是指PC、平板、手机设备之间较大的分辨率差异。实现上不局限于具体的方案,通常结合了 流式布局 + 弹性布局 方案。比如给小屏幕手机设置@2x图,为大屏手机设置@3x图。
    优势:能够使网页在不同设备、不同分辨率屏幕上呈现合理布局,不仅仅是样式伸缩变换
    不足:要匹配足够多的设备与屏幕,一个web页面需要多个设计方案,工作量比较大

       通过媒体查询技术需要设置一定量的断点,到达某个断点前后的页面发生显著变化,用户体验不太友好

    11. HTTP和HTTPS有什么区别?

    HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。

    HTTPS和HTTP的区别主要如下:

    (1)https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

    (2)http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

    (3)http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

    (4)http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

    12. HTTP状态码

  • 相关阅读:
    打开百度要用几步
    web渗透总结
    mysql之基本数据类型
    网络编程
    垃圾回收机制
    常用模块-hashlib,hmac,configparser,subprocess,xlrd,xlwt,xml,re
    常用模块-random,shutil,shevle,logging
    文件操作
    元组、字典、集合数据类型
    基本数据类型之列表类型
  • 原文地址:https://www.cnblogs.com/yjw520/p/15184853.html
Copyright © 2011-2022 走看看