Contents
  1. 1. 1. css 实现一个自适应搜索框,输入框部分宽度自适应,搜索按钮宽度固定
  2. 2. 2. 改变 this 的指向有哪些方法呢?
    1. 2.0.1. a. this 与执行时有关
    2. 2.0.2. b. 改变this指向的方法
      1. 2.0.2.0.1. 1. new关键字改变this指向
      2. 2.0.2.0.2. 2. call()
      3. 2.0.2.0.3. 3. apply()
      4. 2.0.2.0.4. 4. bind()
  • 3. 3. 关于const
  • 4. 4. 数组的方法是哪来的?
  • 5. 5. 请说明 cookie、sessionStorage、localStorage 之间的区别?
    1. 5.0.1. localStorage和sessionStorage
    2. 5.0.2. cookie
    3. 5.0.3. localStorage与sessionStorage vs. Cookies
    4. 5.0.4. 客户端与服务器端
  • 6. localStorage是怎么实现数据保护的?session是怎么记录用户登录状态的
  • @[toc]

    1. css 实现一个自适应搜索框,输入框部分宽度自适应,搜索按钮宽度固定

    使用父级盒子进行包裹,对于文本框使用盒子包裹,使用margin 距离右边距为button留下位置
    对button 使用绝对定位 absolute 进行定位
    盒子内部的input设置宽度为100%
    即可完成输入框大小随窗口变化,而button 大小不改变

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    *{
    padding: 0;
    margin: 0;
    }
    .search {
    height: 35px;
    border: 1px solid black;
    position: relative;
    text-align: center;
    }
    .search_input{margin-right: 110px;}
    .search_input>input{
    width: 100%;
    display: inline-block;
    height: 30px;
    }
    .search_btn>button{
    width: 100px;
    height: 32px;
    background-color: darkcyan;
    position: absolute;
    right: 5px;
    top:4px;
    }
    </style>
    </head>
    <body>
    <div class="search">
    <div class="search_input">
    <input type="text" name="">
    </div>
    <div class="search_btn">
    <button></button>
    </div>
    </div>
    </body>
    </html>

    2. 改变 this 的指向有哪些方法呢?

    a. this 与执行时有关

    在实际的项目开发中,我们经常会遇到需要改变 this 指向的情况。改变 this 的指向有哪些方法呢?

    1. 如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,
      这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题(在严格版中的默认的this不再是window,而是undefined。)

      1
      2
      3
      4
      5
      6
      7
      function a(){
      var user = "追梦子";
      console.log(this.user); //undefined
      console.log(this); //Window
      }
      a(); //相当于window.a();
      //this最终指向的是调用它的对象,这里的函数a实际是被Window对象所点出来的
    2. 如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。

      1
      2
      3
      4
      5
      6
      7
      8
      var o = {
      user:"追梦子",
      fn:function(){
      console.log(this.user); //追梦子
      console.log(this); //{user: "追梦子", fn: ƒ}
      }
      }
      o.fn(); //this执行时被它的上一级对象o{user: "追梦子", fn: ƒ}调用
    3. 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      var o = {
      a:10,
      b:{
      //a:12,
      fn:function(){
      console.log(this.a); //undefind 在b中只有fn没有定义a,所以输出 undefined
      console.log(this);//{fn: ƒ}
      }
      },
      fn1:function(){
      console.log(this.a); //10
      console.log(this) //{a: 10, b: {…}, fn1: ƒ}
      }
      }
      o.fn1(); //this执行时被它的上一级对象o调用 所以fn1中this指向o this.a = a
      o.b.fn();
      o.fn() //Uncaught TypeError: o.fn5 is not a function
    4. 当this遇到return

      1
      2
      3
      4
      5
      6
      7
      function fn()  
      {
      this.user = '追梦子';
      return
      }
      var a = new fn;
      console.log(a.user); //追梦子
    1
    2
    3
    4
    5
    6
    7
    function fn()  
    {
    this.user = '追梦子';
    //return
    }
    var a = new fn;
    console.log(a.user); //追梦子

    return 为空的时候和没有return,this直接指向实例


    1
    2
    3
    4
    5
    6
    7
    function fn()  
    {
    this.user = '追梦子';
    return {};
    }
    var a = new fn;
    console.log(a.user); //undefined
    1
    2
    3
    4
    5
    6
    7
    function fn()  
    {
    this.user = '追梦子';
    return function(){}; //return了一个空函数
    }
    var a = new fn;
    console.log(a.user); //undefined

    reurn指向一个对象,则this指向该对象


    1
    2
    3
    4
    5
    6
    7
    function fn()  
    {
    this.user = '追梦子';
    return 1;
    }
    var a = new fn;
    console.log(a.user); //追梦子
    1
    2
    3
    4
    5
    6
    7
    function fn()  
    {
    this.user = '追梦子';
    return undefined;
    }
    var a = new fn;
    console.log(a.user); //追梦子
    1
    2
    3
    4
    5
    6
    7
    function fn()  
    {
    this.user = '追梦子';
    return null;
    }
    var a = new fn;
    console.log(a.user); //追梦子

    如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。还有一点就是虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。

    1. this 指向最后调用它的对象
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      var o = {
      a:10,
      b:{
      a:12,
      fn:function(){
      console.log(this.a); //undefined
      console.log(this); //window
      }
      }
      }
      var j = o.b.fn;//
      j();

    虽然函数 fn 是被对象 b 所引用,但是在将fn赋值给变量 j 的时候并没有执行所以,当j 执行的时候最终指向的是window

    b. 改变this指向的方法

    1. new关键字改变this指向
    1
    2
    3
    4
    5
    6
    //构造函数版this
    function Fn(){
    this.user = "追梦子";
    }
    var a = new Fn();
    console.log(a.user); //追梦子

    用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份

    相当于下面的代码:

    1
    2
    3
    4
    5
    6
    7
       var a= {
    user: "追梦子",
    Fn: function() {
    console.log(a.user);//console.log(this.user);
    }
    }
    a.Fn()

    2. call()

    把b添加到第一个参数的环境中,简单来说,this就会指向那个对象。

    1
    2
    3
    4
    5
    6
    7
    8
    var a = {
    user:"追梦子",
    fn:function(){
    console.log(this.user); //追梦子
    }
    }
    var b = a.fn;
    b.call(a); //若不用call,则b()执行后this指的是Window对象

    call方法除了第一个参数以外还可以添加多个参数,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var a = {
    user:"追梦子",
    fn:function(e,ee){
    console.log(this.user); //追梦子
    console.log(e+ee); //3
    }
    }
    var b = a.fn;
    b.call(a,1,2);

    3. apply()

    apply方法和call方法有些相似,它也可以改变this的指向,也可以有多个参数,但是不同的是,第二个参数必须是一个数组,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    var a = {
    user:"追梦子",
    fn:function(){
    console.log(this.user); //追梦子
    }
    }
    var b = a.fn;
    b.apply(a);

    参数为数组:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var a = {
    user:"追梦子",
    fn:function(e,ee){
    console.log(this.user); //追梦子
    console.log(e+ee); //11
    }
    }
    var b = a.fn;
    b.apply(a,[10,1]);

    注意如果call和apply的第一个参数写的是null,那么this指向的是window对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var a = {
    user:"追梦子",
    fn:function(){
    console.log(this);
    //Window {external: Object, chrome: Object, document: document, a: Object, speechSynthesis: SpeechSynthesis…}
    }
    }
    var b = a.fn;
    b.apply(null);

    4. bind()

    bind方法和call、apply方法有些不同,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    var a = {
    user:"追梦子",
    fn:function(){
    console.log(this.user);
    }
    }
    var b = a.fn;
    b.bind(a); //代码没有被打印

    我们发现代码没有被打印,对,这就是bind和call、apply方法的不同,实际上bind方法返回的是一个修改过后的函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var a = {
    user:"追梦子",
    fn:function(){
    console.log(this.user);
    }
    }
    var b = a.fn;
    var c = b.bind(a);
    console.log(c); //f() { console.log(this.user); }
    //其实c是a中的fn函数 即 c = a.fn
    c(); //追梦子 == a.fn()

    同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var a = {
    user:"追梦子",
    fn:function(e,d,f){
    console.log(this.user); //追梦子
    console.log(e,d,f); //10 1 2
    }
    }
    var b = a.fn;
    var c = b.bind(a,10);
    c(1,2);

    总结:
    call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var name = 123;
    var a = {
    name: 345,
    sayName: function () {
    console.log(this.name)
    }
    }
    var b = {
    name: 789
    }
    var sayName = a.sayName; //只是将这个函数赋给新变量 sayname
    a.sayName();//345 调用这个函数时this指向 a
    sayName(); //123 调用这个函数时,this指向window
    a.sayName.call(b) //789

    3. 关于const

    1
    2
    3
    4
    5
    6
    7
    function test() {
    if (true) {
    let a = 1;
    const b = { t : 2};
    var c = 3;
    }
    }

    t 的值可以改吗?
    答案是可以,虽然const 是定义个常量,里面保存的是常量的地址
    即保存的是 t 的地址,但是t 的值可以改

    4. 数组的方法是哪来的?

    1
    2
    var str = 'name abc tce';
    var arr = str.split(' ');

    主要想知道Array 的原型链,方法是对象自带的

    5. 请说明 cookie、sessionStorage、localStorage 之间的区别?

    localStorage和sessionStorage

    localStorage和sessionStorage是相对较新的API(意思是,并非所有传统浏览器都支持它们)并且几乎完全相同(包括API和功能),唯一的例外是持久性。sessionStorage(顾名思义)仅在浏览器会话期间可用(并且在选项卡或窗口关闭时被删除) - 然而,它确实存在页面重新加载(源DOM存储指南 - Mozilla开发人员网络)。

    显然,如果您正在存储的数据需要持续可用,那么localStorage比sessionStorage更可取 - 尽管您应该注意两者都可以被用户清除,因此您不应该依赖于任何一种情况下数据的持续存在。

    localStorage和sessionStorage非常适合在页面之间保存客户端脚本中所需的非敏感数据(例如:首选项,游戏中的分数)。存储在localStorage和sessionStorage中的数据可以在客户端/浏览器中轻松读取或更改,因此不应依赖于在应用程序中存储敏感或安全相关的数据。

    对于cookie也是如此,这些可以被用户轻易篡改,并且也可以以纯文本方式从中读取数据 - 因此,如果您想要存储敏感数据,那么会话实际上是您唯一的选择。如果您不使用SSL,cookie信息也可能在传输过程中被截获,尤其是在开放的wifi上。

    从积极的方面来看,通过设置仅HTTP标记,可以从跨站点脚本(XSS)/脚本注入等安全风险中获得一定程度的保护,这意味着现代(支持)浏览器将阻止从JavaScript访问cookie和值(这也会阻止您自己的合法JavaScript访问它们。这对于身份验证cookie尤其重要,身份验证Cookie用于存储包含登录用户详细信息的令牌 - 如果您拥有该cookie的副本,那么就所有意图和目的而言,只要Web应用程序成为该用户,关注,并具有相同的用户访问数据和功能。

    由于cookie用于身份验证和用户数据的持久性,因此对于同一域的每个请求,所有对页面有效的cookie都会从浏览器发送到服务器- 这包括原始页面请求,任何后续Ajax请求,所有图像,样式表,脚本和字体。因此,cookie不应用于存储大量信息。浏览器还可以对可以存储在cookie中的信息的大小施加限制。通常,cookie用于存储用于身份验证,会话和广告跟踪的标识令牌。令牌通常不是人类可读的信息本身,而是链接到您的应用程序或数据库的加密标识符。

    localStorage与sessionStorage vs. Cookies

    在功能方面,cookies,sessionStorage和localStorage只允许您存储字符串 - 可以在设置时隐式转换原始值(这些将需要转换回来,以便在读取后将它们用作类型)但不能转换为对象或数组(JSON可以将它们序列化以使用API​​存储它们)。会话存储通常允许您存储服务器端语言/框架支持的任何基元或对象。

    这是一个范围非常广泛的问题,很多优点/缺点都与情况有关。

    在所有情况下,这些存储机制将特定于单个计算机/设备上的单个浏览器。任何跨会话持续存储数据的要求都需要涉及您的应用服务器端 - 最有可能使用数据库,但可能使用XML或文本/ CSV文件。

    localStorage,sessionStorage和cookies都是客户端存储解决方案。会话数据保存在服务器上,直接由您控制。

    localStorage和sessionStorage
    localStorage和sessionStorage是相对较新的API(意思是,并非所有传统浏览器都支持它们)并且几乎完全相同(包括API和功能),唯一的例外是持久性。sessionStorage(顾名思义)仅在浏览器会话期间可用(并且在选项卡或窗口关闭时被删除) - 然而,它确实存在页面重新加载(源DOM存储指南 - Mozilla开发人员网络)。

    显然,如果您正在存储的数据需要持续可用,那么localStorage比sessionStorage更可取 - 尽管您应该注意两者都可以被用户清除,因此您不应该依赖于任何一种情况下数据的持续存在。

    localStorage和sessionStorage非常适合在页面之间保存客户端脚本中所需的非敏感数据(例如:首选项,游戏中的分数)。存储在localStorage和sessionStorage中的数据可以在客户端/浏览器中轻松读取或更改,因此不应依赖于在应用程序中存储敏感或安全相关的数据。

    饼干
    对于cookie也是如此,这些可以被用户轻易篡改,并且也可以以纯文本方式从中读取数据 - 因此,如果您想要存储敏感数据,那么会话实际上是您唯一的选择。如果您不使用SSL,cookie信息也可能在传输过程中被截获,尤其是在开放的wifi上。

    从积极的方面来看,通过设置仅HTTP标记,可以从跨站点脚本(XSS)/脚本注入等安全风险中获得一定程度的保护,这意味着现代(支持)浏览器将阻止从JavaScript访问cookie和值(这也会阻止您自己的合法JavaScript访问它们。这对于身份验证cookie尤其重要,身份验证Cookie用于存储包含登录用户详细信息的令牌 - 如果您拥有该cookie的副本,那么就所有意图和目的而言,只要Web应用程序成为该用户,关注,并具有相同的用户访问数据和功能。

    由于cookie用于身份验证和用户数据的持久性,因此对于同一域的每个请求,所有对页面有效的cookie都会从浏览器发送到服务器- 这包括原始页面请求,任何后续Ajax请求,所有图像,样式表,脚本和字体。因此,cookie不应用于存储大量信息。浏览器还可以对可以存储在cookie中的信息的大小施加限制。通常,cookie用于存储用于身份验证,会话和广告跟踪的标识令牌。令牌通常不是人类可读的信息本身,而是链接到您的应用程序或数据库的加密标识符。

    localStorage与sessionStorage vs. Cookies
    在功能方面,cookies,sessionStorage和localStorage只允许您存储字符串 - 可以在设置时隐式转换原始值(这些将需要转换回来,以便在读取后将它们用作类型)但不能转换为对象或数组(JSON可以将它们序列化以使用API​​存储它们)。会话存储通常允许您存储服务器端语言/框架支持的任何基元或对象。

    客户端与服务器端

    由于HTTP是无状态协议 - Web应用程序无法在返回网站时识别以前访问的用户 - 会话数据通常依赖于cookie令牌来识别用户重复访问(尽管很少有URL参数可用于同样的目的)。数据通常具有滑动到期时间(每次用户访问时更新),并且根据您的服务器/框架数据将被存储在进程中(意味着数据将在Web服务器崩溃或重新启动时丢失)或外部存在状态服务器或数据库。使用Web场(给定网站的多个服务器)时,这也是必需的。

    由于会话数据完全由您的应用程序(服务器端)控制,因此它是本质上任何敏感或安全的最佳位置。

    服务器端数据的明显缺点是可扩展性 - 在会话期间每个用户都需要服务器资源,并且每个请求都必须发送客户端所需的任何数据。由于服务器无法知道用户是否导航到另一个站点或关闭其浏览器,因此会话数据必须在给定时间后过期,以避免被放弃的会话占用所有服务器资源。因此,在使用会话数据时,您应该意识到数据可能已过期并丢失,尤其是在具有长格式的页面上。如果用户删除其cookie或切换浏览器/设备,它也将丢失。

    一些Web框架/开发人员使用隐藏的HTML输入将数据从表单的一个页面持久保存到另一个页面,以避免会话过期。

    localStorage,sessionStorage和cookie都受“同源”规则的约束,这意味着浏览器应该阻止访问除设置信息开头的域之外的数据。

    localStorage是怎么实现数据保护的?session是怎么记录用户登录状态的

    • localStorage只能存储字符串,非字符串的数据在存储之前会被转换成字符串。所以在存储一些复杂数据类型时可能有些麻烦,通常的做法是先使用JSON.stringfy()方法将其转换为字符串后存储,使用时取出后再使用JSON.parse()方法进行还原。
      引文:https://www.jianshu.com/p/fd6205334b16
      localStorage数据是不会随着网络请求传输给服务端的,所以就不会被其他人截获(相反,cookie是随着每次网络请求传输给后台的)

    • session是保存在服务器端,根据前端发送过来的cookie来判断和设置用户登录状态
      session有很多实现方式,很常见的一种实现是在后端数据库或内存中记录用户的状态,并生成一个sessionId,这个ID会通过cookie返回给浏览器,此后浏览器每次请求的时候都会带上session id,服务端就能获取到用户状态了

    Contents
    1. 1. 1. css 实现一个自适应搜索框,输入框部分宽度自适应,搜索按钮宽度固定
    2. 2. 2. 改变 this 的指向有哪些方法呢?
      1. 2.0.1. a. this 与执行时有关
      2. 2.0.2. b. 改变this指向的方法
        1. 2.0.2.0.1. 1. new关键字改变this指向
        2. 2.0.2.0.2. 2. call()
        3. 2.0.2.0.3. 3. apply()
        4. 2.0.2.0.4. 4. bind()
  • 3. 3. 关于const
  • 4. 4. 数组的方法是哪来的?
  • 5. 5. 请说明 cookie、sessionStorage、localStorage 之间的区别?
    1. 5.0.1. localStorage和sessionStorage
    2. 5.0.2. cookie
    3. 5.0.3. localStorage与sessionStorage vs. Cookies
    4. 5.0.4. 客户端与服务器端
  • 6. localStorage是怎么实现数据保护的?session是怎么记录用户登录状态的