在函数中使用Javascript“this”关键字

问题描述:

我知道Javascript并不是真正的OO语言,并且ECMAScript 6的引入应该可以缓解其中的一些问题,但是在Javascript中使用this关键字真的令我困惑,至少当试图在Javascript中复制“私人”功能时。在函数中使用Javascript“this”关键字

考虑下面的代码:

function Person() { 

    this.name = "Blake"; 

    var sayHi = function() { 
     console.log("Salutations. My name is " + this.name); 

     this.name = "Jon"; 
     console.log("Salutations. My name is " + this.name); 

     this.sayBye(); 
    }; 

    this.callSayHi = function() { 
     console.log("O hai, my name is " + this.name); 
     sayHi(); 
    }; 

    this.sayBye = function() { 
     console.log("Goodbye " + this.name); 
    }; 

}; 

var blake = new Person(); 
blake.callSayHi(); 

callSayHi()功能的情况下,所述上下文是调用callSayHi(),或者blake的对象。所以,this的定义是Person称为blake实例和控制台输出以下:

O hai, my name is Blake 

接下来,sayHi()函数被调用。在这一点上,我会假设,this会提到blake再度但控制台与一些意外的行为,否则说:

Salutations. My name is result 

接下来,我尝试设置神秘this参考,并再次登录到控制台:

Salutations. My name is Jon 

但是,在这一点上,我仍然不知道this指的是什么,只是我已经为它指定了一个属性,并且该属性的旧值为result

最后,检查是否this确实涉及blake,我叫sayBye(),这给了我一个错误:

Uncaught TypeError: undefined is not a function 

所以我知道this并不是指blakesayHi()的情况下; this是指什么呢?它是指sayHi(范围较窄)还是指window(范围较广)?

有什么方法可以让我声明一个函数的上下文是Person,它没有明确地分配给一个属性(类似于像Java这样的语言中的“private”函数)?

最后,一个更普遍的问题:如果thiswindow在我的第一个问题,怎样的this.name定义不绑定到sayHi,相反,结合window?我做了一个叫做Person的函数,而this是指Person在这方面,但是当我做一个函数sayHi,this是指window ......?是不是因为sayHi被定义为:

var sayHi = function() { ... } 

...而不是:

function sayHi() { ... } 

+3

可能重复[如何进行 “this” 关键字的工作?](http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – 2015-02-10 18:24:19

+1

也许下面的答案可以帮助:http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR 2015-02-11 00:57:24

+0

JavaScript是一种OO编程语言。正如你所说,它只是没有实现类模式。但是你有可能实现类似结构的类。而且每个变量都是JavaScript中的一个对象。 – Spectator 2015-02-11 09:21:27

你可能想要的是这样的:

function Person() { 
    this.name = "Blake"; 

    return this; 
}; 
Person.prototype.sayHi = function() { 
    console.log("Salutations. My name is " + this.name); 

    this.name = "Jon"; 
    console.log("Salutations. My name is " + this.name); 

    this.sayBye(); 
}; 

Person.prototype.callSayHi = function() { 
    console.log("O hai, my name is " + this.name); 
    this.sayHi(); 
}; 

Person.prototype.sayBye = function() { 
    console.log("Goodbye " + this.name); 
}; 

var blake = new Person(); 
blake.callSayHi(); 

因此,这里是一些解释:

每个功能都有自己的变量范围此指的是如果你在一个函数中定义的函数时,新功能只在功能中可用,所以它们的上下文来自功能。如果您在原型上定义函数,则函数的上下文就是这样。

希望帮助的