function Developer(skill) {
this.skill = skill;
this.says = function() {
alert(this.skill + ' rocks!');
}
}
var john = new Developer('Ruby');
var func = john.says;
func();
Run Code Online (Sandbox Code Playgroud)
我尝试这个例子时,我得到以下消息,undefined rocks! 而不是Ruby rocks!.你能解释一下为什么会这样吗?
this关键字JavaScript 函数在调用时具有执行上下文,使得this关键字绑定到从中调用它们的对象.如果调用john.says()函数的执行上下文,则会有一个this指向的关键字john.如果您将全局变量分配给在对象上找到func的方法says,john则将执行上下文更改为全局对象.当您调用该func函数时,this取消引用window(或undefined*)和since window.skill是未定义的,says将该值强制转换为字符串以将其与字符串'rocks!'连接.
您可以将函数的副本绑定到对象(有效地锁定它的上下文引用):
var func = john.says.bind(john);
Run Code Online (Sandbox Code Playgroud)
或者,您可以通过在构造函数中使用闭包来关闭相关位:
function Developer(skill){
var _this = this; // we keep a reference here
this.skill = skill;
this.says = function(){
alert(_this.skill + ' rocks!');
// when invoked _this refers to the context at construction
}
return this;
}
Run Code Online (Sandbox Code Playgroud)
您可以skill直接从方法引用该值,因此根本不需要上下文:
function Developer(skill){
// because skill is defined in this context, says will refer to this context
// to get the value of the skill variable.
this.says = function(){
alert(skill + ' rocks!');
}
}
Run Code Online (Sandbox Code Playgroud)
最后的选项是在调用时使用您想要的上下文调用该方法:
func.call(john /*, optional arguments... */);
func.apply(john /*, optional arguments as an array */);
Run Code Online (Sandbox Code Playgroud)
如果我们想在对象实例或类型之间重用一个方法,但在调用时有正确的执行上下文,我们可以使用prototype属性.
function Developer(skill){
this.skill = skill;
this.says();
}
Developer.prototype.says = function(){
alert(this.skill + ' rocks!');
}
var john = new Developer("Ruby"); // alert("Ruby rocks!")
var tony = new Developer("JavaScript"); // alert("JavaScript rocks!")
Run Code Online (Sandbox Code Playgroud)
*"use strict"激活表示JavaScript未来的特殊严格模式.当尚未设置上下文时,此特殊严格执行环境将不会解析为全局对象,而是将其解析为适当的作用域值undefined.
| 归档时间: |
|
| 查看次数: |
126 次 |
| 最近记录: |