• 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)。

  • 相关阅读:
    isa与hasa的关系
    两道笔试题的解法
    无耻的WoW打钱工作室
    我正处于恶性循环中——读wowar上的一篇帖子有感
    snippets from ObjectOriented Thought Process (1)
    使用C#获取当前Windows所设定的时区
    用ASP.NET模拟Windows Service来实现定时提醒之类的功能
    乱说 缓存
    认识数据库连接
    网站sql注入的技巧与防范
  • 原文地址:https://www.cnblogs.com/niconicohang/p/6512276.html
Copyright © 2020-2023  润新知