zoukankan      html  css  js  c++  java
  • js中的this介绍

    今天跟大家一起简单的来了解一下js中一个有趣的东西,this.

      在js中我们用面向对象的思想去编写的时候,各个模块之间的变量就不那么容易获取的到了,当然也可以通过闭包的方式拿到其他函数的变量,如果说每获取一个变量,都要用闭包的方式去获取,就显得太繁琐了,这时候js中也提供了一种方法来获取其他的变量,当然前提是这些函数之间是有联系的,比如函数2是绑在函数1的原型上的,那么函数1中用this指明的一个变量,在函数2中同样可以用this来获取到,当然着其中是有着一定的规则的。那么接下来我给大家对this做一个详细的介绍

    一:到底什么是this呢?

      概念:执行上下文,this一般存在于函数中,表示当前函数的执行上下文, 如果函数没有执行,那么this没有内容,只有函数在执行后this才有绑定。

      注意:this的指向只能是对象,当然别忘记了数组也是一个特殊的对象。

    二:this到底指向的是谁呢?

      this的指向其实是跟this的执行位置是有关的,不同的位置执行位置,this的指向就可能发生改变。

      Tip:this被谁执行了,this就是执行谁的,这时候一定要看清楚this是被谁直接执行的!

      那么接下来给大家总结几种this指向的问题。

    1:默认执行:this指向了window,在严格模式下,this指向了undefined

    eg:
        function fn(){
            "use strict";
            console.log(this);
        }
        fn();
        这个时候在严格模式下,指向的是undefined,去掉严格模式,指向window

    2:隐式执行(通过对象执行):通过上下文对象执行

    tip:隐式执行粗体上分为五种,在隐式执行的过程中,可能会改变执行对象,也可能会出现隐式丢失,从而改变了当前的this

    这里给大家整理五种常见的this错误指向的例子

     2.1改变函数引用

    
        eg:
            var obj = {
                name:'admin',
                show:function(){
                    console.log(this.name);
                }
            }
            var newShow = obj.show;
            newShow();
            //this指向了window,函数的执行对象变成了window

     2.2函数传参

    eg:    
            var name='window';
            var obj = {
                name: 'obj',
                show: function(){
                    console.log(this.name);    
                }    
            }
            function trigger(fn){
                fn();    
            }
            trigger(obj.show);
            //this指向window

    2.3:定时器传参

     var name='window';
            var obj = {
                name: 'obj',
                show: function(){
                console.log(this.name);    
                }    
            }
            setTimeout(obj.show,1000);
            //this指向了window

     2.4:DOM对象事件

     var name = 'window';
            var oHtml = document.documentElement;
            var obj = {
                name: 'obj',
                show: function(){
                console.log(this.name);    
                }    
            }
            oHtml.name = 'DOM';
            oHtml.onclick = obj.show;
            //this指向了window

     2.5:arguments类数组改变this指向问题

    tip:传入过多的实参,多余的实参虽然没有什么用,但也是保存在函数中了
            var length = 10;
            function fn(){
                console.log(this.length);    
            }
            var obj = {
                length: 5,
                method: function(fn){
                    fn();    
                    arguments[0]();
                }
            };
            obj.method(fn,"111","222");
            //打印结果为10,3
            
            tip1:
             obj.method的value并不是一个可以直接直接执行的函数,通过obj.method并不能执行函数,
          所以this指向的并不是obj,输出的不是5,this指向的是function这个无名函数,他的执行对象直接是window,发生隐式丢失 但是arguments[0]();也会执行,因为传入的第一个参数就是一个函数,同时传进了两个多余的实参,所以打印出的为3 tip2: 数组是很特殊的对象,他的索引值相当于是obj2对象中的属性值。所以说数组,类数组也会改变this指向问题。

    3:显示执行

      通过函数的bind或call或apply执行

      tip:当发生隐式执行的时候,还希望能拿到指定的this,可以通过函数的一些方法,强行改变到指定的this

      这里拿bind方法给大家做一下介绍

      blind()方法;执行结束后,会返回一个新函数,新函数是被改变了this和参数的老函数
    bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为this,
    传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。 tip:改变this的指向,简单来说,可以让没有这个功能的对象,具有另一个对象的功能 当blind();有多个参数的时候,第一个参数表示this的指向,其他的参数会与原函数的参数一起放在新函数中 eg1:
    var a = { name:"admin" } var b = { name:"uesr", show:function(){ console.log(this.name); } } b.show(); var c = b.show.bind(a); c(); //此时的c能够获取到a里面的name,利用a强行将this指向了a eg2: 常用方式,用来改变函数内计时器函数this的指向 for(var i=0;i<ali.length;i++){ ali[i].onclick = function(){ setTimeout(function(){ console.log(this) }.bind(this),500) } } //不用blind()方法,this直接指向的是window,强行给计时器函数加了blind()方法,这时候谁触发了函数的执行,this就指向了谁。

    4:new绑定

      利用面向对象思想编程的时候,我们通过new创建这个函数对象的时候,那么这个this就指向了被new出来的对象,也就是所谓的new绑定

    注:以上知识均为本人总结原创,转载请著名博客出处:https://www.cnblogs.com/jiuxia/


    作者:九夏
    出处:https://www.cnblogs.com/jiuxia/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    android SQLite使用
    蓝牙从搜索到成功配对的全过程
    vscode 开发.net core 从安装到部署 教程详解
    ServiceStack 简单服务搭建
    MongoDB 安装配置
    request.url 端口 错误
    Python 之 hello world
    .NET DateTime 源码学习
    Parallel.For 平行算法 使用
    Thread.Join 和 Task.Wait 方法
  • 原文地址:https://www.cnblogs.com/jiuxia/p/11488140.html
Copyright © 2011-2022 走看看