欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-09 13:02:48
...

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