Skip to content

Latest commit

 

History

History
114 lines (95 loc) · 3.77 KB

2019-11-05.md

File metadata and controls

114 lines (95 loc) · 3.77 KB

question

  • js中function是不是都具有prototype属性?如果不是那那些具有哪些不具有?

    • 不是所有函数都有prototype属性。 一般函数都会有prototype,以下几种不具有
    • 箭头函数
    • Function.prototype.bind()生成的函数不具有 why? ecmascript明文规定 因为new的时候this指向原函数 和返回的函数没关系
    • Math.ceil、ParseInt、alert等 内置函数(built-in-function)他们不会作为constructor 所以不具有prototype
  • 可以new的函数都有哪些要求?哪些函数不可以使用new?举例说明

    • 一定要具备[[Construct]]结构,和prototype没有必然关系

      let foo = function(){
        this.name = 'hahaha'
      }
      let obj = {};
      let foo1 = foo.bind(obj);
      let person = new foo1();
      //上面例子中foo1.prototype为undefined ,但是可以使用new来声明对象
    • 箭头函数、Math.ceil、ParseInt、alert等都不可以使用new来声明

  • new具体做了什么?用原生代码实现new的功能?

    1、创建一个空的简单JavaScript对象(即{});
    2、链接该对象(即设置该对象的构造函数)到另一个对象 
    3、将步骤1新创建的对象作为this的上下文 
    4、如果该函数没有返回对象,则返回this。
    function new(fn){
      let o = {};
      o._proto_ = fn.prototype;
      let res = fn.call(o);
      return typeof(res)==='object' ? res : o;
    }
  • bind、apply、call的区别?原生代码实现功能?

    //1、call和apply的区别就是参数形式 这里不做重点讨论 
    Function.prototype.call = function(context,...rest){
      context.fn = this;
      let res = context.fn(...rest);
      delete context.fn
      return res;
    }
    //2、bind函数实现 特点:返回函数并非立即执行;依赖apply;考虑函数作为constructor时的情况
    Function.prototype.bind = function(){
      if (typeof this !== 'function') {
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not 				callable');
      }
    
      var aArgs   = Array.prototype.slice.call(arguments, 1),
          fToBind = this,
          fNOP    = function() {},
          fBound  = function() {
            // this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
            return fToBind.apply(this instanceof fBound
                                 ? this
                                 : oThis,
                                 // 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
                                 aArgs.concat(Array.prototype.slice.call(arguments)));
          };
      if (this.prototype) {
        // 当执行Function.prototype.bind()时, this为Function.prototype 
        // this.prototype(即Function.prototype.prototype)为undefined
        fNOP.prototype = this.prototype; 
      }
      //使用fNOP主要是不让fBound.prototype的修改影响到this.prototype
      fBound.prototype = new fNOP();
      return fBound;
    }
  • 改变this的方法有哪些?优先级是怎样的?

    1、默认绑定  fn() 严格模式下 undefined  非严格模式下 全局变量 window或者globel
    2、隐式绑定 
      var name = 'hi';
      let say = function(){
        alert(this.name)
      } 
      let obj = {
        name:"haha"
        say:say
      }
      say();
      obj.say();
      //函数的参数传递也是隐式绑定 这就是回调函数容易找不到this的原因 隐式绑定丢失this;
      function say(){
        console.log(this.name);
      }
    	let cat = {
        name:"cat",
        say:say
      }
      var name = 'animal';
    	setTimeout(obj.foo,100)
    2、显示绑定bind、call、apply
    3、new绑定
    4、优先级
      new绑定>call\apply\bind > 隐式绑定>默认绑定