专栏首页牛客网头条前端实习面试

头条前端实习面试

头条前端实习面试

作者:offer-hunter

链接:https://www.nowcoder.com/discuss/155934?type=2&order=3&pos=11&page=1

来源:牛客网

一面二面紧挨着,视频面试只把记住的几个题记下来了

其余的都是我的 project 相关,没有列出来的必要

这是我放在印象笔记的,所以还有当时实现的代码

也不知道对不对,大家看的时候还能帮我找找错 嘿嘿 :)

js实现继承

这是我当时实现的

function Animal(){
    this.type = 'animal'
}
function dog(){
    Animal.call(this)
    dog.prototype = Animal.prototype
    dog.prototype.constructor = dog
}

不应该把Animal的原型给dog,这样对于dog原型链操作会影响到父类

正确的实现应该是

/**
 * js 继承实现
 */
const log = console.log
;
(function () {
    function Person() {
        this.name = "ownNamePerson"
    }
    Person.prototype.move = function move(params) {
        log('I am person, can move')
    }
    function Woman(n) {
        // 如果 父类不需要参数初始化
        Person.call(this)
        //如果父类需要参数初始化
        // super(arguments[2]) 翻译成
        //Person.call(this,arguments[2])
        this.name = "iamWoman"
        this.actualName = n
    }
    Woman.prototype = Object.create(Person.prototype)
    // 也可以这样写,不过多调用了一次Person的构造函数
    // Woman.prototype = new Person()
    Woman.prototype.inWomanPrototype = function inWomanPrototype(params) {
    }
    Woman.go = function go(params) {
    }
    Woman.prototype.constructor = Woman
    // 不能这么写,Woman 也需要有自己的原型链,这样Woman直接使用了Person的 prototype
    //当Woman.prototype.go = function name(params) {
    // }
    // 会影响Person的prototype
    // Woman.prototype = Person.prototype
    // ---------test-------------------------
    let woman = new Woman("iam woman name")
})();

实现bind

我当时的实现

Function.prototype.bind = function bind(fn) {
    let that = this
    let args = arguments
    return function () {
        fn.call(that, args)
    }
}
function test() {
    let that = this
}
let obj = {
    name: "wwc"
}
let newtest = test.bind(obj)
newtest()

正确的实现

let b = Function.prototype.bind
Function.prototype.bind = Function.prototype.bind || function bind(ctx) {
    let that = this
    let slice = Array.prototype.slice
    let bindArgs = slice.call(arguments,1)
    // bind可以传递参数,返回的被绑定的函数同样可以传参,所以这里先保存第一次bind的参数,忽略ctx,从 index 1 开始
    // 后面将调用时的参数传递进去,concat成一个array
    return function b(args) {
        // slice.call 将 arguments 转换为 Array
        that.apply(ctx,bindArgs.concat(slice.call(arguments)))
      // From https://stackoverflow.com/a/960870/7529562
      //NOTE: The slice function is intentionally generic; it does not require that its this value be an Array object.
      //Therefore it can be transferred to other kinds of objects for use as a method.
      // Whether the slice function can be applied successfully to a host object is implementation-dependent.
      //Therefore, slice works on anything that has a length property, which arguments conveniently does.
    }
}
function test (a,b) {
    console.log(arguments)
}
let obj = {
    name: "wwc"
}
let newtest = test.bind(obj,'1','2')
newtest('3','4')
给一段代码判断执行顺序
// 判断下面输出顺序
console.log('begin');
setTimeout(() => {
    console.log('setTimeout 1');
    Promise.resolve()
        .then(() => {
            console.log('promise 1');
            setTimeout(() => {
                console.log('setTimeout2');
            });
        })
        .then(() => {
            console.log('promise 2');
        });
    new Promise(resolve => {
        console.log('a');
        resolve();
    }).then(() => {
        console.log('b');
    });
}, 0);
console.log('end');
给出代码判断this指向
let a = {b: function() { console.log(this) }, c: () => {console.log(this)}}
a.b()
a.c()
let d = a.b
d()

html文件解析过程,浏览器的重排,重绘

浏览器的渲染机制,为什么使用Virtual DOM,直接操作DOM的弊端是什么?

补全下面代码

function repeat(func, times, wait) {
}
// 输入
const repeatFunc = repeat(alert, 4, 3000);
// 输出
// 会alert4次 helloworld, 每次间隔3秒
repeatFunc('hellworld');
// 会alert4次 worldhellp, 每次间隔3秒
repeatFunc('worldhello')

我当时的实现

function repeat(func, times, wait) {
    let timer
    let count = 1
    function set(f) {
        timer = setTimeout(() => {
            func(f)
            if (count >= times) {
                clearTimeout(timer)
                return
            }
            set(f)
            count++
        }, wait)
    }
    return set
}
// 输入
const repeatFunc = repeat(alert, 4, 3000);
// 输出
// 会alert4次 helloworld, 每次间隔3秒
repeatFunc('hellworld');

这种实现如果调用两次 repeatFunc

一共会输出4次,因为 count 被公用了

而且只能接受一个参数

当时更好的写法没有想出来

面试官到最后给了一个写法,但是有错误,

改完之后:

async function wait(seconds) {
    return new Promise((res) => {
        setTimeout(res, seconds);
    });
}
function repeat(func, times, s) {
    return async function (...args) {
        for (let i = 0; i < times; i++) {
            func.apply(null, args);
            await wait(s);
        }
    };
}
let log = console.log
let repeatFunc = repeat(log,4,3000)
repeatFunc('HelloWorld')
repeatFunc('WorldHello')
输出
HelloWorld
WorldHello
HelloWorld
WorldHello
HelloWorld
WorldHello
HelloWorld
WorldHello
最初给的是
async function wait(seconds) {
    return new Promise((res) => {
        setTimeout(res, seconds);
    });
}
async function repeat(func, times, s) {
    return function (...args) {
        for (let i = 0; i < times; i++) {
            func.apply(null, args);
            await wait(s);
        }
    };
}

首先, 必须在 async 中使用 await

所以

return async function (...args) {

}

再者, async 函数返回值会被 Promise 包装

所以 async function repeat(){} 返回 Promise,并不是我们想要的 async function

所以这里去掉 async

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • (22/24) webpack实战技巧:静态资源集中输出

    工作中会有一些已经存在但在项目中没有引用的图片资源或者其他静态资源(比如设计图、开发文档),这些静态资源有可能是文档,也有可能是一些额外的图片,而在打包时保留这...

    wfaceboss
  • 小结ES6基本知识点(六):模块的语法

    ES6初学者,通过阅读本文可对ES6知识点有个大体的概念,强烈建议阅读阮一峰大大的ES6入门。

    前端林子
  • (8/24) 图片跳坑大战--css中的图片处理

    前言:此节的开展是在上一节的基础上进行的,(每一节都是从无到有编写关于此节的知识),最后会附上相关完整代码。上一节

    wfaceboss
  • (21/24) webpack实战技巧:webpack对三方类库的优化操作

    在前面的学习中我们对于如何引入第三方类库(Jquery)推荐了两种方式,第一种是import引入的方式,第二种是ProvidePlugin插件。那两种引入方法有...

    wfaceboss
  • (7/24) 插件配置之html文件的打包发布

    从前面几节到现在,其实我们的项目结构是有问题的,因为我们直接把index.html文件放到了dist文件夹目录下。这肯定是不正确的,应该放到我们src目录下,然...

    wfaceboss
  • (14/24) css进阶:(入门)去除冗余的css

    在平时的项目开发中,我们会引入一些框架,比如:Bootstrap,但是在项目中通常我们只使用它的一小部分,还有部分是冗余的。更有甚有时候需求更改,带来DOM结构...

    wfaceboss
  • (17/24) webpack实战技巧:生产环境和开发环境并行设置,实现来回切换

    --开发依赖:就是开发中用到而发布时用不到的。在package.json里面对应的就是devDependencies下面相关配置。

    wfaceboss
  • 你还在一个字一个字敲代码吗?【vscode snippets 入门教程】

    可能你用过一些 snippets ,也就是我们平时说的代码片段,就是只要敲几个字母,自动生成一大段代码,例如 React 创建一个组件的 snippets(如下...

    志航
  • (23/24) webpack实战技巧:如何在webpack环境中使用Json

    在webpack1或者webpack2版本中,若想在webpack环境中加载Json文件,则需要加载一个json-loader的loader进来的。但是在web...

    wfaceboss
  • (20/24) webpack实战技巧:watch实现热打包和添加代码备注

    在前面的学习中,我们一直使用webpack-dev-server充当(本地)服务器和完成打包任务,但是当出项目团队联合开发,共同使用一个服务器时,这时候我们需要...

    wfaceboss

扫码关注云+社区

领取腾讯云代金券