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 次 |
最近记录: |