美文网首页
this与new、call、apply、bind的关系

this与new、call、apply、bind的关系

作者: 琢磨先生lf | 来源:发表于2018-06-23 09:12 被阅读29次

什么是this

this的指向在函数定义的时候是确定不来的,只有函数执行的时候,才能确定。
this的最终指向是那个调用它的对象,确切的说,是它的上级父对象,父对象有可能包含在其他对象中。
示例:

    <script>
        var name = "tom";
        function M() {
            console.log(this);
        }
        M();    // window
        var o1 = {
            name: 'o1',
            fun: M
        }
        o1.fun();  // o1
        var o2 = {
            name: 'o2',
            o3 : {
                name: 'o3'
            }
        }
        o2.o3.fun = M;
        o2.o3.fun();    // o3
    </script>

对于构造函数中的this

在《原型链》中我们提到过new的本质:

  1. 创建一个空对象o,o继承自构造函数原型
  2. 执行构造函数,指定执行上下文为o,使o获取到构造函数的属性和方法
  3. 判断执行构造函数的返回,如果是对象则返回该对象,否则返回o
    示例:
function newObject(func) {
  var o = Object.create(func.prototype);
  var k = func.call(o);
  if (typeof(k) === 'object'&&k !== null) {
    return k;
  } else {
    return o;
  }
}

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
这里引出一个知识点:

  1. 在new的语法中,实例对象赋值给谁,this指向的就是谁,确切的说,其实this指向的是示例中的o或k,具体看返回
  2. 当构造函数中this碰到return,跟示例中一样,如果返回类型是个对象(k),那么this就指向这个新对象,否则返回指向函数的实例(o)
    示例:
    <script>
        function M1() {
            return {
                name: 'M1'
            }
        }
        function M2() {
            return 1;
        }
        function M3() {
            return null;
        }
        var m1 = new M1();  // {name: 'M1'}
        var m2 = new M2();  // M2
        var m3 = new M3();  // M3,虽然typeof null='object',但是在这里this还是指向那个函数的实例,因为null比较特殊
    </script>

call、apply、bind

相同点:

  • 接收多个参数
  • 改变了函数执行时this指向,指向为第一个入参对象

不同点:

  • call、apply会立即执行函数,bind不执行,返回新的函数对象,需调用
  • call、bind支持从第二个参数开始传多个参数,apply只传两个参数,除第一个指定对象外还可以传一个数组形式的参数
    示例:
    <script>
        var name = 'joe'
        function M(job, age) {
            console.log(this.name, job, age);
        }
        var o = {
            name: 'tom', job: 'student', age: 17
        }
        M('rose', 16);                      // joe rose 16
        M.call(o, o.job, o.age);            // tom student 17
        M.apply(o, [o.job, o.age]);         // tom student 17
        var f = M.bind(o, o.job, o.age);    // tom student 17
        function K(job, age) {
            var o1 = {name: 'lilei'}
            M.apply(o, arguments);
        }
        K(o.job, o.age);                    // tom student 17
    </script>

相关文章

网友评论

      本文标题:this与new、call、apply、bind的关系

      本文链接:https://www.haomeiwen.com/subject/xyllyftx.html