面试中经常遇到的一些编程题

310 阅读1分钟
  1. 为Function扩展一个方法bindX,可以实现如下功能
  function add(num1, num2) {
      return this.value + num1 + num2;
  }

  var data = {
      value: 1
  };

  var addEx = add.bindX(data, 2);

  addEx(3);    // 6

这是考察的是es3中怎么实现bind,可以这么写

Function.prototype.bindX = function(o) {
    var boundArgs = arguments, self = this;
    return function () {
        var args = [],index;
        for (index = 1; index < boundArgs.length; index++) {
            console.log(boundArgs[index])
            args.push(boundArgs[index]);
        }
        for (index = 0; index < arguments.length; index++) {
            console.log(arguments[index])
            args.push(arguments[index]);
        }
        return self.apply(o, args);
    }
}

或者这样

Function.prototype.bindX = function(context) {
    var args = Array.prototype.slice.call(arguments,1);
    var self = this;
    return function() {
        var innerArgs = Array.prototype.slice.call(arguments,0);
        return self.apply(context, args.concat(innerArgs));
    }
}
  1. 写一个instanceOf函数实现和instanceOf一样的效果

    /* object instanceOf contructor
    *	instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
    */
    function instanceOf(left, right) {
        var rightCon = right.prototype;
        left = left.__proto__;
        while(true) {
            if (left === null) {
                return false;
            }
            if(left === rightCon) {
                return true;
            }
            left = left.__proto__;
        }
    }
    
  2. 已知如下对象,请基于es6的proxy方法设计一个属性拦截读取操作的例子,要求实现去访问目标对象example中不存在的属性时,抛出错误:Property “$(property)” does not exist

    const man={
        name:'jscoder',
        age:22
    }
     //补全代码
    const proxy = new Proxy(...)
    proxy.name //"jscoder"
    proxy.age //22
    proxy.location //Property "$(property)" does not exist
    
    const man={
        name:'jscoder',
        age:22
    }
    const handler = {
        get: function(obj, property) {
            if (!(property in obj)) {
                throw new Error('Property "' + property +'" does not exist');
        	}
            return obj[property];
        }
    };
    const proxy = new Proxy(man, handler);
    
  3. 已知数据结构users,请实现语法支持user.unique能够按照name字段去重,并输出结构为:[“a”,“b”]

    var users=[{
       id:1,name:"a"
    },{
       id:2,name:"a"
    },{
       id:3,name:"b"
    },{
       id:4,name:"v"
    }]
    
    var users=[{
       id:1,name:"a"
    },{
       id:2,name:"a"
    },{
       id:3,name:"b"
    },{
       id:4,name:"v"
    }]
    Array.prototype.unique = function () {
        let set = new Set();
        const _arr = this;
        _arr.map(item => set.add(item.name));
        return [...set];
    }
    users.unique();
    
  4. 给出如下虚拟dom的数据结构,如何实现简单的虚拟dom,渲染到目标dom树

    //样例数据
    let demoNode = ({
        tagName: 'ul',
        props: {'class': 'list'},
        children: [
            ({tagName: 'li', children: ['douyin']}),
            ({tagName: 'li', children: ['toutiao']})
        ]
    });
    
    <ul class="list">
        <li>douyin</li>
        <li>toutiao</li>
    </ul>
    
    var elem = Element({
        tagName: 'ul',
        props: {'class': 'list'},
        children: [
            (Element({tagName: 'li', children: ['douyin']})),
            (Element({tagName: 'li', children: ['toutiao']}))
        ]
    });
    // Element类
    function Element({tagName, props, children}) {
        if (!(this instanceof Element)) { // 实现不需要new就可以创建Element对象实例
            return new Element({tagName, props, children});
        }
        this.tagName = tagName;
        this.props = props || {};
        this.children = children || [];
    }
    // 给Element添加render
    Element.prototype.render = function() {
        var el = document.createElement(this.tagName),
            props = this.props;
        for (prop in props) {
            el.setAttribute(prop, props[prop]);
        }
        this.children.forEach(child => {
            var childEl;
            if (child instanceof Element) {
            	    childEl = child.render();
            } else {
                childEl = document.createTextNode(child);
            }
            el.append(childEl);
        });
        return el;
    }
    
    document.body.append(elem.render());