头条前端实习面试

一面二面紧挨着,视频面试只把记住的几个题记下来了
其余的都是我的 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

#实习##前端工程师##面经##字节跳动#
全部评论
begin, end, setTimeout1, resolve(), a, resolve(), promise1, b promise2, setTimeout2
点赞 回复 分享
发布于 2019-02-25 16:58
大佬过了嘛
点赞 回复 分享
发布于 2019-02-25 16:34
你第一种写法,让count变量放到返回函数里,别放闭包不就不公用了么?
点赞 回复 分享
发布于 2019-02-25 22:33
楼主大几?
点赞 回复 分享
发布于 2019-02-25 22:38
有算法吗
点赞 回复 分享
发布于 2019-02-25 23:04
我给出最后一题我的正确实现 function repeat(func, times, wait) { function set(f) { let timer let count = 1 let print = () => { timer = setTimeout(() => { func(f) if (count >= times) { clearTimeout(timer) return } print(f) count++ }, wait) } print() } return set } // 输入 let log = console.log const repeatFunc = repeat(log, 4, 3000); // 输出 // 会alert4次 helloworld, 每次间隔3秒 repeatFunc('hellworld'); repeatFunc('1111')
点赞 回复 分享
发布于 2019-02-26 08:31
统一回复,我收到了头条的offer,但无奈的是入职的前一天被学校拦下来了,不让大三实习, 最后没办法,不能入职了,只能到暑假重新面试,真是尴尬
点赞 回复 分享
发布于 2019-03-08 08:34
在加上一题,第三面的,用css实现立方体,注意,是立方体。
点赞 回复 分享
发布于 2019-03-08 08:36
最后一个js题直接用闭包就好了 function repeat(func, times, wait) { var run = function() { let currentTime = 0 let content = arguments[0] return (function next() { setTimeout(() => { func(content) currentTime++ if (currentTime < times) { next() } }, wait) })() } return run }
点赞 回复 分享
发布于 2019-03-22 10:35
function repeat(func, times, wait) { var run = function() { let currentTime = 0 let content = arguments[0] return (function next() { setTimeout(() => { func(content) currentTime++ if (currentTime < times) { next() } }, wait) })() } return run }
点赞 回复 分享
发布于 2019-03-22 10:36
function wait(seconds) {   return new Promise(resolve => {     setTimeout(resolve, seconds);   }); } function repeat(func, times, s) {   return async function (...args) {     for (let i = 0; i < times; i++) {       func.apply(null, args);       await wait(s);     }   }; } const repeatFunc = repeat(alert, 4, 2000); repeatFunc("hellworld");//会alert4次 helloworld,每次间隔3秒
点赞 回复 分享
发布于 2019-09-07 17:14
编程题很多吗?基础问的多吗?
点赞 回复 分享
发布于 2019-12-13 00:53
repeat那道题,我也给一个思路,大家可以参考 function* inner(func, text, times) {     for (let i = 0; i < times; i ++) {         yield func(text)     } } function repeat2(func, times, interval) {     return function (text){         let innerFunc = inner(func, text, times)         let inter = setInterval(() => {             let res = innerFunc.next()             if (res.done) {                 clearInterval(inter)             }         }, interval)     } }
点赞 回复 分享
发布于 2021-01-03 19:40
6***委托:currentTarget与target有什么区别与联系?
点赞 回复 分享
发布于 2021-02-22 16:29

相关推荐

我也曾抱有希望:说的好直白
点赞 评论 收藏
分享
7 119 评论
分享
牛客网
牛客企业服务