前端常见面试题(八)@郝晨光

作者: 郝晨光 | 来源:发表于2019-07-11 23:20 被阅读181次

    ES5/ES6 的继承除了写法以外还有什么区别?

    1. ES5寄生组合式继承(只是列举一个方法,ES5继承还有很多实现方式)
    function Parent(name) {
        this.name = name;
    }
    Parent.prototype.say = function() {
        console.log(this.name);
    };
    
    function Child(name,sex) {
        Parent.call(this,name);
        this.sex = sex;
    }
    
    const ChildProtoType = Object.create(Parent.prototype);
    ChildProtoType.constructor = Child;
    Child.prototype = ChildProtoType;
    Child.constructor = Child;
    Child.prototype.getSex = function() {
        console.log(this.sex);
    };
    
    let child = new Child('张三','男');
    console.log(child);
    child.say();
    child.getSex();
    
    ES5继承
    1. ES6继承
    class Parent {
        constructor(name) {
            this.name = name;
        }
        say() {
            console.log(this.name);
        }
    }
    class Child extends Parent {
        constructor(name, sex) {
            super(name);
            this.sex = sex;
        }
        getSex() {
            console.log(this.sex);
        }
    }
    let child = new Child('李四', '女');
    console.log(child);
    child.say();
    child.getSex();
    
    ES6继承

    ES6中子类继承父类的属性使用了super关键字,ES6语法实现是ES5的语法糖,表面上,ES6的类关键字和子类继承关键字 实现的结构和ES5继承一样,但是根本还是有差别的,ES5继承prototype属性是先实例化父类,直接继承;而 ES6是在实例化子类对象时继承父类的prototype,即实例化父类。


    http状态码有哪些?分别是什么意思?

    1. 1**(信息类):表示接收到请求并且继续处理
      • 100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
    2. 2**(响应成功):表示动作被成功接收、理解和接受
      • 200 OK 正常返回信息
      • 201 Created 请求成功并且服务器创建了新的资源
      • 202 Accepted 服务器已接受请求,但尚未处理
    3. 3**(重定向类):为了完成指定的动作,必须接受进一步处理
      • 301 Moved Permanently 请求的网页已永久移动到新位置。
      • 302 Found 临时性重定向。
      • 303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。
      • 304 Not Modified 自从上次请求后,请求的网页未修改过。
    4. 4**(客户端错误类):请求包含错误语法或不能正确执行
      • 400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
      • 401 Unauthorized 请求未授权。
      • 403 Forbidden 禁止访问。
      • 404 Not Found 找不到如何与 URI 相匹配的资源。
    5. 5**(服务端错误类):服务器不能正确执行一个正确的请求
      • 500 Internal Server Error 最常见的服务器端错误。
      • 503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。


    浏览器是如何渲染页面的?

    1. 简述浏览器渲染过程

      1. 解析HTML以构建DOM树:渲染引擎开始解析HTML文档,转换树中的html标签或js生成的标签到DOM节点,它被称为 — 内容树。
      2. 构建渲染树:解析CSS(包括外部CSS文件和样式元素以及js生成的样式),根据CSS选择器计算出节点的样式,创建另一个树 — 渲染树。
      3. 布局渲染树: 从根节点递归调用,计算每一个元素的大小、位置等,给每个节点所应该出现在屏幕上的精确坐标。
      4. 绘制渲染树: 遍历渲染树,每个节点将使用UI后端层来绘制。
    2. CSS阻塞渲染

      • CSS 是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。
      • 这就是为什么我们将外部样式的引入放在head标签中的原因,在body渲染前先把相对完整CSSOM Tree构建好。
    3. JavaScript阻塞渲染

      • JavaScript 会阻止 DOM 构建和延缓网页渲染。 为了实现最佳性能,可以让您的JavaScript 异步执行,并去除关键渲染路径中任何不必要的 JavaScript。

    详细链接:

    1. 浏览器如何渲染页面
    2. [ JS 进阶 ] Repaint 、Reflow 的基本认识和优化

    typeof 和 instanceof 相同点与不同点

    相同点
    typeofinstanceof 都用来判断一个变量的数据类型。
    不同点:

    1. typeof返回值是一个字符串, 用来说明变量的数据类型。
    2. typeof一般只能返回如下六个数据类型,null会返回Object,若参数为引用类型,始终返回object :number, boolean, string, function, object, undefined。
    3. instanceof返回一个布尔值。
    4. instanceof一般用来判断一个变量是否来自某个引用类型的实例,判断在其原型链中是否存在一个构造函数的prototype属性,如:
      •  console.log([] instanceof Array); // true
         console.log([] instanceof Object); // true
        
    5. 可以看到的是[]是来自于Array是没有问题的,返回值为true;但是[] instanceof Object也为true是我们不想看到的,这是因为在javascript中,Object是最顶级的数据类型,所有的引用类型最终都会指向Object
    6. 对于这种情况,我们可以使用ES6新增的Array.isArray([])来进行判断,也可以通过[].constructor === Array来判断

    如何解决回调地狱?请手写代码

    一、拆解function

    function methodOne() {
        fs.readFile(url, (err, content) => {
            // do some thing
        })
    }
    function methodTwo() {
        fs.readFile(url, (err, content) => {
            // do some thing
            methodOne()
        })
    }
    fs.readFile(url, (err, content) => {
        if(!err) {
             methodTwo()
        }
    })
    

    二、事件发布/监听模式
    前端常见面试题(七)@郝晨光 实现异步的几种方法中 3. 发布者订阅者模式
    三、Promise

    function syncMethod() {
        return new Promise((reslove, reject) => {
              if(true) {
                    reslove('success! do some thing')
              }else {
                    reject('error message!')
              }
        })
    }
    syncMethod().then(res => {
        console.log(res);
        return syncMethod();
    }).then(res => {
        console.log(res);
    })
    

    四、Generator

        function *syncMethod() {
            yield 1;
            yield 2;
            yield 3;
            return 4;
        }
        let generator = syncMethod();
        console.log(generator.next()); // {value: 1, done: false}
        console.log(generator.next()); // {value: 2, done: false}
        console.log(generator.next()); // {value: 3, done: false}
        console.log(generator.next()); // {value: 4, done: true}
    

    五、async/await

    1. function拆分的方式其实仅仅只是拆分代码块,时常会不利于后续维护;
    2. 事件发布/监听方式模糊了异步方法之间的流程关系;
    3. Promise虽然使得多个嵌套的异步调用能够通过链式的API进行操作,但是过多的then也增加了代码的冗余,也对阅读代码中各阶段的异步任务产生了一定干扰;
    4. 通过generator虽然能提供较好的语法结构,但是毕竟generator与yield的语境用在这里多少还有些不太贴切。
    5. 所以就有了async/await语法糖
    // 模拟获取数据
    function getData() {
        return 'response';
    }
    // async函数
    async function syncMethod() {
        let res = await getData(); // 等待异步结束,将结果保存在变量中
        console.log(res); // 一般异步的话,await后边会跟随一个Promise对象,调用.then方法来获取值
    }
    syncMethod()
    

    结言
    感谢您的查阅,代码冗余或者有错误的地方望不吝赐教;菜鸟一枚,请多关照

    相关文章

      网友评论

        本文标题:前端常见面试题(八)@郝晨光

        本文链接:https://www.haomeiwen.com/subject/veqjkctx.html