zoukankan      html  css  js  c++  java
  • js中对this指向的理解

    牢记:this是在函数执行的时候回才明确他的执行的上线文。

    1.以函数的形式调用时,this永远都是window。比如fun();相当于window.fun();

     

    2.以方法的形式调用时,this是调用方法的那个对象

     

    3.以构造函数的形式调用时,this是新创建的那个对象

     

    4.使用call和apply调用时,this是指定的那个对象

     

    先看一下下面的例子

    例1

    var name = "The Window";
    var object = {
      name: "My Object",
      getNameFunc: function () {
        return function () {
          return this.name;
        };
      }
    };
    console.log(object.getNameFunc()());
    //
    The Window
    
    

    object.getNameFunc()调用返回一个函数。再调用的时候指向window

    例2 

    var name = "The Window";
    var object = {
      name: "My Object",
      getNameFunc: function () {
        var that = this;
        return function () {
          return that.name;
        };
      }
    };
    console.log(object.getNameFunc()());
    // My Object

    相比于上面的代码,这个是用到了闭包,相当于我们在object对象中把this保存到一个变量that中,所以打印的是Object.

    例3

    function Foo() {
       getName = function () { alert (1); };
       return this;
    }
    Foo.getName = function () { alert (2);};
    Foo.prototype.getName = function () { alert (3);};
    var getName = function () { alert (4);};
    function getName() { alert (5);}
    
    //请写出以下输出结果:
    Foo.getName();
    getName();
    Foo().getName();
    getName();
    new Foo.getName();
    new Foo().getName();
    new new Foo().getName();
    //2 4 1 1 2 3 3

    解读代码:一共5句话:第一句定义了一个叫Foo的函数,第二句为Foo创建了一个叫getName的静态属性,存储了一个匿名函数;第三句为Foo的原型对象新创建了一个叫getName的匿名函数。第四句定义了一个函数表达式getName的函数,第五句声明了一个叫getName的函数。

    在执行之前会进行变量的提升,函数的整体提升,注意Foo函数中的getName是全局变量

    考察了 js运算符的优先级 ()> . >new . 为成员访问的意思。

    输出:

    1 Foo.getName();访问Foo函数存储的属性, 弹出2

    2 getName(); 函数表达式变量提升,函数声明整体提升,表达式的赋值在下面,会覆盖函数声明的部分, 弹出 4

    3 Foo().getName(); 先执行Foo函数,然后调用Foo函数的返回值对象的getName属性函数。

    Foo函数的返回值为this,这里直接执行Foo函数,所以this指向window对象;所以这里相当于执行window.getName(),注意Foo函数中的getName是全局变量,当执行Foo函数的时候会重新给getName赋值,也就是alert(4)函数,将此变量的值赋值为 function(){alert(1)}。 弹出1

    4 getName();因为第三步在执行Foo函数的时候已经重新给getName赋值,所以 弹出 1

    5 new Foo.getName();这里考察了js中的元素符 实际上应该是new(Foo.getName)();这里把Foo.getName函数当做了构造函数来执行,访问Foo函数存储的属性, 弹出2

    6 new Foo().getName(); 这里相当于(new Foo()).getName();执行前面一部分

    (new Foo()),有返回值,返回的类型为this,而this在构造函数中代表的是当前实例化对象,然后调用的是实例化对象的getName函数,(而本题中没有给实例化对象添加任何属性(因为构造函数的后面的小括号里面灭有传任何参数))所以会到当前对象的原型对象上去寻getName,所以弹出是3 。

    关于构造函数的返回值:

    1 没有返回值则按照其他语言一样返回实例化对象。

    2 若有返回值检查返回值是否为引用类型。若是基本类型,则与无返回值相同,实际返回歧视例化对象;若是引用类型,则实际返回值为这个引用类型

    7 new new Foo().getName();同第6问,弹出的为3 

     

    。。。。。仅仅作为了解this。。。。

     

    例4

     function A(x){
    this.x = x;
    }
    A.prototype.x = 1;
    
    function B(x){
    this.x = x;
    }
    B.prototype new A();//这句意思是B的实例的原型对象为A;继承了A的原型中
    的属性
    var a = new A(2), b = new B(3);
    delete b.x;
    
    console.log(a.x)
    console.log(b.x)

    代码执行完以后,a.x和b.x的结果是什么?分别为:2,undefined

    第一个输出为2,直接给构造函数A传进去一个参数(2),输出为2,没有问题。

    第二个输出为undefined,delete表示的是把B上的x属性被删除了,所以会去原型链上去找,B继承A,先去A的内部找,找到了为undefined。

  • 相关阅读:
    我的DBDA类文件
    登录时的验证码怎么写?
    phpcms 制作简单企业站的常用标签
    HTML 基础知识
    目标
    split函数的实现
    myString操作符重载
    cout中的执行顺序_a++和++a
    二叉树的层次遍历法
    树的前中序遍历_求后续遍历
  • 原文地址:https://www.cnblogs.com/jwenming/p/14441444.html
Copyright © 2011-2022 走看看