zoukankan      html  css  js  c++  java
  • js 爱恨情仇说 this

    this 相信大家在写代码的时候都会遇到,可是怎么样才能用好this,估计这个还是有点困难的,虽然你有时候你会用到,但是他所在的具体的几个场景中所代表的是什么意思了?可能这个你就不是很清楚啊。这个就会在你使用的过程中出现很多的问题,于是今天我们来总结一下this,到底这个this?他真的有想象中的那么难吗?

    其实可以总结为一句话:this指的是调用函数的那个对象

    于是我们可以总结出this的四个调用场景:

    (1) 方法模式:简单的说就是使用点表达式或是下标表达式来调用 这里定然是有对象的 这种情况下 this的绑定发生在调用的时候 绑的自然是调它的那个对象了。

    于是我们看一下下面这个例子:也是博客园里面我感觉比较经典的一个例子:

    var x = 2;
    function test() {
        alert(this.x);
    }
    test();//2
    这里text():出来的数据是2 其实我们可以这么理解:
    var window.x = 2;
    function test() {
        alert(window.x);//
    }
    window.test();//2
    
    
    var x = 2; 
    function test()
    { this.x = 0; }
    test();
    alert(x);//0
    换一种写法
    var
    window.x = 2;
    function test()
    { window
    .x = 0; }
    test();
    alert(window.x);
    //0

    大家能不能明白第一种方式的方法了。

    2)函数模式:这个就更简单了,函数名加调用运算符('()')。不过要小心,这个this绑的可是全局对象,不管你写哪了。(可以理解成  你不给我指明了   我就自己给它加个全局对象)
    当一个函数作为函数调用而不是方法调用时,这个this关键字引用全局对象。容易混淆的是,当一个嵌套的函数(作为函数)在一个包含的函数中调用,而这个包含的函数是作为方法调用的,这也是成立的:this关键字在包含的函数中有一个值,但是它却(不太直观地)引用嵌套的函数体的内部的全局对象。

    var a = 'global';
    var obj = {
        a : 'local',
        test : function(){
            function test1(){
                alert(this.a);//global 这是为什么呢?其实每个函数在被调用时,其活动对象都会自动获取两个特殊的变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问到外部函数中的这两个变量了。这个比较蛋疼了怎么办啊?
            }
            alert(this.a);//local
            test1();
        }
    };
    obj.test();

    下面我们将上面的代码简化看一下到底怎么回事啊?
    var a = 'global';
    var obj = {
        a : 'local',
        test : function(){
            alert(this.a);//local  其实我们可以这样写  alert(obj.a)
        }
    };
    obj.test(); 能不能理解到了啊

    针对上面的问题我们提出如下的结局方案:

    var a = 'global';
    var obj = {
        a : 'local',
        test : function(){
            var that = this; //this的指向实际是指向它的调用的 这个理解对不对了希望纠正啊?
            function test1(){
                alert(that.a);//local
            }
            test1();
        }
    };
    obj.test();

    3)构造器调用模式  一句话就是用new来调用的  new的时候this就绑定到新对象上了  比较好理解
    1.new运算符后面必须跟着一个函数调用。new创建了一个新的没有任何属性的对象,然后调用该构造函数,把新的对象作为this关键字的值传递。
    2.构造函数通常没有返回值。它们初始化作为this的值来传递的对象,并且没有返回值。但一个构造是允许返回一个对象值,并且如果它这么做,返回的对象成为new表达式的值。在此情况下,作为this的值的对象会被抛弃。

    var person = function (string){
        this.name = string
    }
    person.prototype.getName = function (){
        return this.name
    }
    
    var myperson = new person('lin');
    myperson.getName(); 
    如果在一个函数前面带上一个new来调用,那么将创建一个隐藏到该函数的prototype成员的新对象,同时this将会被绑定到那个新对象上。new前缀也会改变return语句的行为。

    可是在构造的原理到底什么样子的了?看着有点晕啊?

     function newOperator(Constr, args) {
         var thisValue = Object.create(Constr.prototype); // (1)
         var result = Constr.apply(thisValue, args);
         if (typeof result === 'object' && result !== null) {
             return result; // (2)
         }
         return thisValue;
    }
    参看地方@大额_skylar  佩服。引用一下

    4)apply,call调用模式  apply,call是函数对象的方法,你想把谁绑定到this 就直接把它作为第一个参数传给apply或call就好了。

    var a= {n: 'lin'};
    var b = function (){
        return this.n;
    }
    console.log(b.apply(a, null));//输出lin

    希望园友指正。继续努力加油 。下一个篇闭包了

    我打算下面写一个专们研究这个的今天就不说了。继续努力。。。。。。希望园友指正

  • 相关阅读:
    Codeforces 691A Fashion in Berland
    HDU 5741 Helter Skelter
    HDU 5735 Born Slippy
    HDU 5739 Fantasia
    HDU 5738 Eureka
    HDU 5734 Acperience
    HDU 5742 It's All In The Mind
    POJ Euro Efficiency 1252
    AtCoder Beginner Contest 067 C
    AtCoder Beginner Contest 067 D
  • 原文地址:https://www.cnblogs.com/linfangshuhellowored/p/4248540.html
Copyright © 2011-2022 走看看