zoukankan      html  css  js  c++  java
  • 头条内推面补坑-更新中

    老样子,答的好的这里就不写了。只记录答的不好的的。
    这次暴露出来的问题就是要多做项目,多实践。

    1.改这个代码

    //目标代码
    const obj = {
        name: " jsCoder",
        skill: ["es6", "react", "angular"],
        say: function () {
            for (var i = 0, len = this.skill.length; i < len; i++) {
                setTimeout(function(){
                    console.log(i);
                    console.log(this.skill[i]);
                }, 0)
                console.log(i);
            }
        }
    };
    obj.say();
    

    第一种:

    const obj = {
        name: " jsCoder",
        skill: ["es6", "react", "angular"],
        say: function ()
        {
            var that = this;
            for (var i = 0, len = this.skill.length; i < len; i++)
            {
                setTimeout((function()
                {
                    console.log(i);
                    console.log(that.skill[i]);
                })(i), 0)
                console.log(i);
            }
        }
    };
    obj.say();
    
    

    结果:
    这里写图片描述
    面试官当时就让我写在浏览器里的,但是我当时使用的webstorm,用的node环境,就报错了,结果就很慌。。。。。搞得最后不敢交。。这个代码可以在浏览器中执行的。

    第二种:
    同时在Node和浏览器(chrome)中都可以实现的:

    const obj = {
        name: " jsCoder",
        skill: ["es6", "react", "angular"],
        say: function ()
        {
            var that = this;
            for (let i = 0, len = this.skill.length; i < len; i++)
            {
                (function () {
                    setTimeout(function () {
                        console.log(i);
                        console.log(that.skill[i])
                    })
                })(i)
                console.log(i);
            }
        }
    };
    obj.say();
    

    结果是这样
    这里写图片描述

    两种结果虽然取到了我们想要的结果,但是和外层的console.log(i)出现了顺序的差异。第二种写法先打印完这个,再依次打印()()自执行函数的。
    应该是执行第一个script宏任务的时候,遇到了三个()(),把这三个推进了微任务,当第一个宏任务结束之后,依次执行完本次遇到的所有的微任务。

    第一种顺序打印,是因为每个setTimeout即是一次宏任务。但如果把setTimeout包括起来就是微任务了。

    其他更多骚方法我都写在这里:

    const obj = {
        name: " jsCoder",
        skill: ["es6", "react", "angular"],
        say: function () {
            this.skill.forEach(function(item,index){
                setTimeout(function(){
                    console.log(index)
                    console.log(item);
                },0)
            })
        },
        say2:function(){
            for (var i = 0, len = this.skill.length; i < len; i++) {
                setTimeout(function(i,item){
                    console.log(i);
                    console.log(item);
                },0,i,this.skill[i]);
            }
        },
        say3:function () {
            let i = 0;
            const arr = this.skill.slice();
            function self_shift() {
                //shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。空返回undefined
                const item = arr.shift();
                if(item) {
                    console.log(i);
                    console.log(item);
                    i++;
                    setTimeout(self_shift, 0);
                }
            }
            setTimeout(self_shift,0);
        }
    };
    obj.say();
    obj.say2();
    obj.say3();
    
    // 闭包了,里面的i跟外面的i不是同一个,加上自执行
    const obj = {
        name: " jsCoder",
        skill: ["es6", "react", "angular"],
        say: function () {
            for (var i = 0, len = this.skill.length; i < len; i++) {
                setTimeout(((j) => {
                    return () => {
                        console.log(j);
                        console.log(this.skill[j]);
                    }
                })(i), 0)
                console.log(i);
            }
        }
    };
    obj.say();
    
    const obj = {
        name: " jsCoder",
        skill: ["es6", "react", "angular"],
        say: function () {
            var that = this;
            for (let i = 0, len = this.skill.length; i < len; i++) {
                setTimeout(function(){
                    console.log(i);
                    console.log(that.skill[i]);
                }, 0)
                console.log(i);
            }
        }
    };
    obj.say();
    

    2.手写bind,bind还有其他什么作用?

    这个内容较多,我另开了一篇博客好好说这个:http://www.cnblogs.com/zhangmingzhao/p/8660985.html

    3.什么时候304什么时候200,相关浏览器缓存问题?

    1. 在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,:
      Last-Modified: Fri, 12 May 2006 18:53:33 GMT

    2. 客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:
      If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT
      服务器端的程序先取得这个字段的值,然后与服务器上的数据最后修改时间对比,如果服务器端的资源没有变化,就直接返回 304 Not Modified 状态码,然后停止。这样就节省了传输数据量,达到节省带宽的目的。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。(发送200?)从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。

    3. 但是Last-Modified不是全能的,后来在Http1.1加入了Etag来标记,Etag的精确度更高
      想象在这个一个情景——客户端上某个资源保存的缓存时间过期了,但这时候其实服务器并没有更新过这个资源,如果这个资源数据量很大,客户端要求服务器再把这个东西重新发一遍过来,是否非常浪费带宽和时间呢?
      所以就有了Etag:
      当你第一次请求一个资源的时候,server会同时生成并返回一个字符串在响应头里,叫Etag。
      浏览器接到资源后,缓存资源的同时也会把这个Etag保存下来,成为If-None_Match 。Etag可以看作是一个资源的唯一标识,当你第二次请求这个资源的时候,请求头里会带着这个Etag,server会拿server该资源现在的Etag跟请求头中的If-None_Match做对比,然后看看If-Modified-Since过没过期,如果一样,直接告诉他:你就用本地的吧,我没变,就不给你返回了。所以返回了304,304就是这样。

    4. 200 From Cache
      这个虽然是200,但他根本就没有跟server做交互,直接拉的本地缓存。

    5. 与浏览器缓存相关的还有Expires字段,这个字段存储的时间是相对服务器而言,无法保证和客户端时间统一”的问题,http1.1新增了 Cache-Control 来定义缓存过期时间,若报文中同时出现了 Pragma、Expires 和 Cache-Control,会以 Cache-Control 为准。Last-Modified之后的Etag就是为了解决,因为如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。

    4.手写一个jsonp,怎么返回数据的?

  • 相关阅读:
    javascript里面this机制的几个例子
    把List<string>集合,编程string,并以“,”号分割
    比较集合List<T>集合,前后多了哪些数据,少了哪些数据Except
    c# Web.config中 windows连接数据库
    MVC之图片验证码
    匿名函数-简单实例
    c# 如何找到项目中图片的相对路径
    MVC下 把数据库中的byte[]值保存成图片,并显示在view页面
    MVC下form表单一次上传多种类型的图片(每种类型的图片可以上传多张)
    关于Visual Studio未能加载各种Package包的解决
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/8648130.html
Copyright © 2011-2022 走看看