this、call和apply

this

JavaScript里面的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。

大致分为下面四种:

  • 作为对象的方法调用
  • 作为普通函数调用
  • 构造器调用
  • Function.prototype.call 或 Function.prototype.apply调用

1.作为对象的方法调用

  var obj = {
            name : 'zs',
            getName : function(){
                console.log(this === obj);//true
                console.log(this.name);//zs
            }
        };
        obj.getName();

2.作为普通函数调用

  var name = 'zs';
        var getName = function(){
            return this.name;
        }
        console.log(getName());// return zs   这里的调用等同于window.getName() 所以this指向window对象

  var age = 18;
        var Obj = {
            age : 22,
            getAge : function(){
                return this.age;
            }
        };
        var getAggetAgee = Obj.getAge;
        console.log(getAge());// return 18 这里也是在全局环境下面调用getAge,所以this也是指向window

//大致来说,this指向当前函数被调用的那个环境。上面两个方法都是在window下面被调用,所以this就指向了window

还有一种情况是,我们有时需要在回调函数里面使用this,但这个时候this往往不是我们预期的那个样子。这个时候,我们可以使用一个变量先保存this

  var obj = {
            name : 'zs',
            getName : function(){
                return this.name;
            },
            bindEvent : function(){
                var that = this;
                document.getElementById('dom').addEventListener('click',function(){
                    console.log(that.getName());
                })
            }
        }
        obj.bindEvent();//this.getName is not a function  这里的this指向了这个dom元素,所以找不到getName方法
//可以使用下面这种方法解决
      bindEvent : function(){
                var that = this;
                document.getElementById('dom').addEventListener('click',function(){
                    console.log(that.getName());
                })
            }

3.构造器调用
JavaScript中没有类,但是可以通过构造器创建对象,同时也提供了new运算符,使的构造器看起来更像一个类。
在JS中,除了浏览器提供的一些内置函数,大部分JavaScript函数都可以当做构造器使用。构造器的外表和普通函数基本一模一样,区别主要在于被调用的方式。当使用new运算符调用函数时,这个函数就可以理解为构造函数(其实只是构造调用,和普通的函数还是一样的,只是调用的方式不一样),该函数总会返回一个对象,通常情况下,构造器里的this就指向返回的这个函数

  var MyFunc = function(){
            this.name = 'zs';
        }
        var func = new MyFunc();
        console.log(func.name);//return  zs

需要注意:如果使用new调用构造函数时,构造函数主动返回了一个object类型的对象,那么此次的运算结果最终会返回这个对象,而不是我们之前期待的this

var MyFunc = function(){
            this.name = 'zs';
            return {
                name : 'ls'
            }
        }

        var func = new MyFunc();
        console.log(func.name);//return  ls

如果构造器不显示的返回任何数据,或者是返回一个非对象类型的数据,就不会造成上面的问题(例如:上面那里如果是 return '123',是不会造成问题的)

4.Function.prototype.call和Function.prototype.apply调用
和普通的函数调用相比,call和apply可以动态的改变传入的this,他们的区别主要在接受的参数格式上
如果传入的第一个参数为null,函数体内的this会指向默认的宿主对象,浏览器里面是window
call(this,arg1,arg2...)
apply(this,[arg1,arg2])

  var obj = {
            name : 'zs',
            getName : function(){
                return this.name;
            }
        };

        var anotherObj = {
            name : 'ls'
        };

        console.log(obj.getName());//return zs
        console.log(obj.getName.call(anotherObj));// return ls

Math.max.apply(null,[1,2,3,4]);//4
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容