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状态码

  • 相关阅读:
    How to create jar for Android Library Project
    Very large tabs in eclipse panes on Ubuntu
    64bit Ubuntu, Android AAPT, R.java
    Linux(Ubuntu)下如何安装JDK
    Configure xterm Fonts and Colors for Your Eyeball
    建立、配置和使用Activity——启动其他Activity并返回结果
    建立、配置和使用Activity——使用Bundle在Activity之间交换数据
    建立、配置和使用Activity——启动、关闭Activity
    建立、配置和使用Activity——Activity
    异步任务(AsyncTask)
  • 原文地址:https://www.cnblogs.com/yjw520/p/15184853.html
Copyright © 2011-2022 走看看