搜尋

首頁  >  問答  >  主體

javascript - 大家來幫我看看這個程式是怎麼運作的?

        var name = "this is window"
        var a = {
            name:"this is a",
            callname:function(){
                alert(this.name)
            }
        }
        function B(){
            alert(this.name)//this is B
        }
        B.prototype.name = "this is B";
        B.prototype.callname = function(){
            alert(this.name)
        }
        B.callname = function(){
            alert(this.name)
        }
        //a.callname()
        //B.callname()
        //(new B()).callname()

最後三個分別得出的是什麼值? ? ?

滿天的星座滿天的星座2842 天前558

全部回覆(2)我來回復

  • 某草草

    某草草2017-05-19 10:43:16

    造成你疑惑的原因有三點:
    第一, 你定義的name屬性,函數本身就有這麼一個屬性也叫name,擾亂了你對這個問題的理解。
    第二, prototype沒有理解好:函數的prototype中定義的屬性,只有實例化(即new操作)後的物件可以用 “變數.屬性” 的方式取得其值。
    第三, this沒有理解好: this指涉的是呼叫方法的物件

    在回答你的問題前,我們先來看一個例子

    var function X() {};
    console.log(X.name);  
    // 输出 "X", 
    // 任何函数都有一个叫做name的属性,其值为该函数名。

    接下來一個一個拆解你的問題 (請使用Chrome瀏覽器的開發者工具驗證)

    1. B.callname() 輸出什麼?

      function B(){
        alert(this.name);
      }
      B.prototype.name = "this is B";
      B.callname = function(){
        alert(this.name)
      };

      B是一個函數,它的 name="B", B.callname這方方法被調用,調用者是B,那麼 callname方法中的this就是指代B, B.name還記得是什麼嗎? 往上看第一個例子就明白了。

      答案是  弹窗显示 “B”。

      你會追問,為什麼不是 B.prototype.name定義的"this is B"? 因為B的prototype中定義的屬性只能被B的實例直接存取。
      你還是不信,那麼請你將所有的 name 都改個名,例如 xname ,本題的答案就變為了 undefined

    2. a.callname() 輸出什麼?

      var a = {
        name:"this is a",
        callname:function(){    
            alert(this.name);
        }
      };

      a本身就是個物件實例,它採用JSON方式定義。 以上程式碼相當於

      a.name = "this is a";
      a.callname = function() {
            alert(this.name);
      }

      callname的呼叫者是a,那麼callname中的this就是a

      答案显而易见 弹窗显示  “this is a”
      
    3. (new B()).callname() 輸出什麼?

      function B(){
        alert(this.name);
      }
      B.prototype.name = "this is B";
      B.callname = function(){
        alert(this.name)
      };

      首先, new B()先執行, 建立了一個匿名實例,我們暫且給他命名為b, 即b = new B(), 函數B中的this此時被指代為b, 然後才是依序執行B函數體內的方法alert, b.name是什麼? b是個實例,它本身沒有name屬性, 就會去父類別的prototype定義中找name,找到了"this is B".new B()先执行, 创建了一个匿名实例,我们暂且给他命名为b, 即 b = new B(), 函数B中的this此时被指代为 b, 然后才是依次执行B函数体内的方法alert, b.name是什么?b是个实例,它本身没有name属性, 就会去父类的prototype定义中找name,找到了 "this is B".
      然后, b.callname() 然後, b.callname()執行, callname中定義的this此時指涉了方法呼叫者b, 實例b本身沒有name屬性, 它會去找到父類別中prototype的name屬性值回傳.

      答案是它会触发两次弹窗: 第一次弹窗 “this is B”, 第二次弹窗也是“this is B”
      

    回覆
    0
  • 迷茫

    迷茫2017-05-19 10:43:16

    第一個中,this表示物件a,所以彈出this is a
    第二個中,B 表示函數B,彈出的是函數的名字B
    第三個會先彈出this is B,因為實例化的時候會執行函數。然後會有一個語法錯誤,是因為 (new B()) 前面的語句沒有加分號。如果沒有語法錯誤的話,還會再彈出一個 this is B,是因為實例物件呼叫原型物件上的 name 屬性。

    回覆
    0
  • 取消回覆