面试之笔试篇(JS内置原型方法)

本文总结了JavaScript面试中常见的笔试题目,包括new的实现、Promise、call/apply、bind、JSON操作以及继承等方法的编写。通过这些实例,帮助面试者理解和掌握JavaScript核心概念,同时欢迎分享更多高级技巧。
摘要由CSDN通过智能技术生成

1. 实现一个new

先看一个真实的new

var Dog = function (name){
    this.name = name
}

Dog.prototype.getName = function(){
    return this.name
}

var dog = new Dog('miao')
console.log(dog.getName()) // 'miao'

实现一个_new函数

function _new(fn, ...args){
    var obj = Object.create(fn.prototype)
    var ret = fn.apply(obj, args)
    return (ret instanceof Object ? ret : obj)
}
//如果构造函数有返回值,并且是对象,还有可能是return new xx() 类似这样的
var Foo = function(){
    return {
        name: 'xx'
    }
}

var dog = _new(Dog, 'wang')
console.log(dog.getName()) // 'wang'

var xx = _new(Foo)
console.log(xx.name) // 'xx'

2. 手写Promise

可参考之前写的一篇手写Promise,主要还是要弄懂链式调用的实现机制。

3. 实现一个call或apply

 Function.prototype.call1 = function(context = window, ...args){
    context.fn = this;
    const result = context.fn(...args)
    delete context.fn;
    return result;
 }

 Function.prototype.apply1 = function(context, args){
    context = context || window; //修复this指定为null时的情况
    context.fn = this;
    const result = context.fn(...args)
    delete context.fn;
    return result;
 }

测试代码

 //测试call和apply
var obj = {
    name: 'xxx',
    getName: function(str){
        return this.name + str
    }
}
var name = '我是全局变量'
console.log(obj.getName.call1(obj, '哈哈'))
console.log(obj.getName.call1(undefined, '哈哈'))
console.log(obj.getName.apply1(null, ['哈哈']))

4. 实现一个bind

// 实现一个bind

Function.prototype.bind1= function(context, ...args){
    if(typeof this != "function") {
        throw Error("not a function")
    }
    const fn = this;
    const resFn = function(argsRs){
        // 这里考虑使用new调用的情况 new的优先级高于显示绑定
        return fn.apply((this instanceof resFn) ? this : context,args.concat(...argsRs))
    }
    // 考虑原型链的问题,使用了寄生式组合继承
    // function create(proto){
    //     function tmp(){}
    //     tmp.prototype = proto;
    //     return new tmp()
    // }
    // resFn.prototype = create(this.prototype);
    resFn.prototype = Object.create(this.prototype);
    return resFn 
}

// 测试
var obj1 = {
    name: 'xx1'
}
const foo = obj.getName.bind1(obj1, 'haa')
foo('111') //xx1haa

5. JSON.parse()

// 实现一个JSON.parse()

var parse = function(str){ 
    return (new Function('return '+ str))()
}

6. 实现一个JSON.stringify

/**
 * 思路:
 * 1.对 number、null、boolean、string基础类型数据原样返回,“undefined|函数” 返回 undefined
 * 2. 引用类型,删除值为“undefined|函数” 的对象属性,将值为 “undefined|函数” 的数组元素输出为null
 * 3. 关于深层嵌套的对象,递归即可
 */
// 值是 undefined|函数
function isUnDefOrFun(type) {
   return  /undefined|function/.test(type);
}

function isString(val){
    return typeof val === 'string'
}

function stringify(obj) {
    const type = typeof obj
    // obj不是对象
    if ( type !== "object") {
        // “undefined|函数” 返回 undefined ,其他的直接加 "" 返回
        if(isUnDefOrFun(type)){
            return  undefined
        }else {
            return  `"${obj}"`
        }
    } else {
        // 分数组和对象两种
        let str = '';
        const isArray = Array.isArray(obj)
        for(let k in obj){
            let val = obj[k]
            const t = typeof val
            // 这里要对null 进行排除
            if(t === "object" && val !== null){
                str += `,"${k}":${stringify(val)}`
            }else{
                if(isString(val)) val = `"${val}"`;
                if(isArray){
                    if(isUnDefOrFun(t)){
                        val = null
                    }
                    str += `,${val}`
                }else{
                    if(!isUnDefOrFun(t)){
                        str += `,"${k}":${val}`; 
                    }
                }
            }
        }
        str = str.substring(1)
        return (isArray ? `"[${str}]"`: `"{${str}}"`)
    }
}

7. 实现一个继承

// 实现一个继承
function Parent(name){
    this.name = name
}

Parent.prototype.getName = function(){
    return this.name
}

function Child(name, parentName){
    Parent.call(this, parentName)
    this.name = name
}

function create(obj){
    function F(){}
    F.prototype = obj;
    return new F()
}
Child.prototype = create(Parent.prototype)
Child.prototype.constructor = Child
// Child.prototype = Object.create(Parent.prototype)

var child = new Child('小明', '美呀')
console.log(child.name)
console.log(child.getName())

8. 实现Object.creat

//实现一个Object.create()
function create(obj){
    function F(){}
    F.prototype = obj
    return new F()
}

9. 实现一个instansOf

// 实现一个instanceOf
// 右边的原型在左边的原型链上可以找到
function instanceOf(left, right){
    let proto = left.__proto__
    const prototype = right.prototype
    while(true){
        if(proto === null) return false
        if(proto === prototype) return true
        proto = proto.__proto__
    } 
}

var a = {
    name: 'xxx'
}
console.log(instanceOf(a,Object))

10. 实现一个flat

[[1,2],[3]].flat() => [1,2,3]

Array.prototype.flat1 = function() {
    //递归
    let arr = this // 拿到实例
    let ret = []
    for (let item of arr) {
        if (Array.isArray(item)) {
            ret.push(...item.flat1())
        } else {
            ret.push(item)
        }
    }
    return ret
}

持续更新中…
如果你正在面试,希望能帮到你,如果你有更牛逼的方法,也欢迎一起交流~~~

微信:yuan_zi_xxx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值