zoukankan      html  css  js  c++  java
  • JavaScript tips:Function调用模式对this的影响

    近来,学习了一下《JavaScript精粹》,读到了函数这章,理清了JavaScript中this在不同调用模式下的指向。

    1、Function调用模式:Function是JavaScript的一种引用类型,拥有四种调用模式:方法调用模式,函数调用模式,构造器调用模式,apply(call, bind)调用模式

    2、Function的不同调用模式对this产生不同的影响:

    (1)方法调用模式:Function作为对象的方法被调用。此时,this指向调用Function的对象。

    1 var obj = {
    2    name: "lucy", 
    3    printName: function( ) {
    4        console.log( this.name );  // 此时printName,作为obj的方法被调用,this指向调用printName的obj,this.name === "lucy"。
    5    } 
    6 };

    (2)构造器调用模式:Function作为构造器被调用,亦即使用new操作符,创建新的对象实例,并且将this指向新创建的对象实例;同时,执行构造器内的代码为新的对象实例添加成员,最后返回这个新的对象实例。

     1 // 创建构造器Demo,在Demo被new操作符调用时,this指向Demo的prototype。
     2 var Demo = function( ){
     3    this.name = "jack";
     4 };
     5 
     6 // 在Demo的prototype中,添加方法printName。
     7 Demo.prototype.printName = function( ){
     8    console.log(this.name);
     9 };
    10 
    11 // 创建Demo实例,此时this已经指向Demo的prototype 
    12 var d = new Demo( );
    13 console.log(d.name);      // 在控制台输出"jack"
    14 d.printName( );           // 在控制台输出"jack"  

    PS:构造函数、构造器只是在英译中的过程中的翻译用词差异,在英文都是constructor。《JavaScript精粹》译为构造器,《JavaScript高级程序设计》第三版译为构造函数。

    (3)apply(call, bind)调用模式:JavaScript中,函数也是对象而具有方法,其具有方法apply。apply接受两个参数,第一个是要传递给this的值,第二个是参数数组。当函数调用apply方法时,将函数内部的this指向apply传递的第一个参数。

     1 var people = {
     2     this.name = "lily";
     3 }
     4 
     5 var printName = function( ){
     6     console.log(this.name)
     7 }
     8 
     9 //  此时apply将this指向了people
    10 printName.apply(people)     // 在控制台输出 lily

    PS:《JavaScript精粹》中只提及apply。apply和call在功能上是相同的,但是具体的使用方式上,有小差异。

    (4)函数调用模式:既不是作为方法调用,也不是调用自己的apply(call, bind),也不是作为构造器被new调用,这时候调用就是函数调用模式。此时函数内部的this指向全局变量,在浏览器中指的是window变量,在node.js中指的是global变量。

    1 window.name = "bob";
    2 
    3 // 此时this指向window
    4 var printName = function( ) {
    5     console.log( this.name );
    6 };
    7 
    8 console.log(window.name)    // 在控制台输出bob
    9 printName()                           // 在控制台输出bob

    以setTimeout(callback, time)为例:

     1 window.name = "bush";
     2 
     3 // 在全局作用域
     4 setTimeout(function( ){
     5     console.log(this.name);    // 在控制台输出"bush"
     6 }, 100);
     7 
     8 // 在对象方法内部
     9 var obj = {
    10    name : "trump",
    11    printName : function( ){
    12       var _this = this;
    13       setTimeout(function( ){
    14           console.log(_this.name);         // 在控制台输出"trump"
    15           console.log( this.name );        // 在控制台输出"bush"
    16       }, 1000);    
    17    }
    18 };
    19 obj.printName();

    3、小结:

    (1)方法调用模式:this指向调用方法的对象。

    (2)构造器调用模式:this指向构造器的创建的实例对象。

    (3)apply调用模式:this指向apply传入的第一个对象。

    (4)函数调用模式:this指向全局对象window(node中指向global)。

  • 相关阅读:
    剑指Offer-11.二进制中1的个数(C++/Java)
    剑指Offer-10.矩形覆盖(C++/Java)
    剑指Offer-9.变态跳台阶(C++/Java)
    UVA 1608 Non-boring sequence 不无聊的序列(分治,中途相遇)
    UVA1607 Gates 与非门电路 (二分)
    UVA 1451 Average平均值 (数形结合,斜率优化)
    UVA 1471 Defense Lines 防线 (LIS变形)
    UVA 1606 Amphiphilic Carbon Molecules 两亲性分子 (极角排序或叉积,扫描法)
    UVA 11134 FabledRooks 传说中的车 (问题分解)
    UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
  • 原文地址:https://www.cnblogs.com/niconicohang/p/6512276.html
Copyright © 2011-2022 走看看