面试常遇的手写原生JS方法

112 阅读1分钟
  • 1)new

运算符创建一个对象类型或具有构造函数的内置对象的实例。

function myNew(Foo,...args){
  let obj={};//创建一个对象
  obj.__proto__ = Foo.prototype;//该对象[[Prototype]]链接指向Foo的prototype
  let res = Foo.call(obj,...args);//改变this指向从Foo换成obj
  return typeof res=='object'?res:obj;//如果函数返回没有Object对象,就返回该对象
}
//例子
function A(name){
  this.name=name;
}
var a = new A("a");//A {name: 'a'}
var b = myNew(A,"b")//A {name: 'b'}

如果你没有使用 new 运算符, 构造函数会像其他的常规函数一样被调用,  并*不会创建一个对象 *在这种情况下, this 的指向也是不一样的。

  • 2) call 和apply差别在于apply参数是[]类型

fn.call(b,...args);把fn函数提供给b执行,并把fn里面的this指向b


Function.prototype.myCall = function(target,...args){
  target.fn = this;//给目标对象target添加属性fn,指向this (原函数fn);
  let res =target.fn(...args);//执行函数,函数中this指向点前面的target对象
  delete target.fn;//销毁释放内存
  return res;
}
  • 3) bind

和call比较bind返回一个待执行的函数,执行函数和call效果一样

被bind后的函数,没办法再次用call改变this指向

Function.prototype.myBind = function(target,...agr1){
  target.fn = this;
  return function(...agr2){//返回一个函数,功能和call一样
    let res =target.fn(...arg2);
    delete target.fn;//销毁释放内存
    return res;
  }
}
  • 4) instanceOf
function myInstanceOf(L,R){
  //L通过__proto__查找能否找到R.prototype,找到返回true,如果指向到Object.prototype还未找到返回false
  //只要L.__proto__不是null且没有找到R.prototype就一直找
  while(L.__proto__&&L.__proto__!=R.prototype){
    L= L.__proto__;
  }
  return  L.__proto__==null?false:true;
}
  • 5) Object.create

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

Object.prototype.myCreate = function(target){
  function F(){};
  F.prototype=target;
  return new F();
}