Javascript 如何绑定';这';prototype.object上的上下文是否正确?
代码示例:Javascript 如何绑定';这';prototype.object上的上下文是否正确?,javascript,scope,Javascript,Scope,代码示例: function Test() { this.name = 'test' } Test.prototype.normal = function() { console.log('normal', this.name); }; Test.prototype.special = { name: 'special', start: function () { console.log("special", this.name); }
function Test() {
this.name = 'test'
}
Test.prototype.normal = function() {
console.log('normal', this.name);
};
Test.prototype.special = {
name: 'special',
start: function () {
console.log("special", this.name);
}
}
test = new Test;
test.normal(); // Response 'normal, test'
test.special.start(); // Response 'special, special'
我想要special.start
函数记录“special,test”
我怎样才能做到这一点?我使用的是coffeescript,所以一个咖啡示例会很受欢迎,但是一个javascript示例也可以!提前谢谢 我想你的问题是关于函数中的这个参数。尝试使用apply或call方法
test=function(){this.name='test';}
test.prototype.special={name:'special',start:function(){alert(this.name)}
var t=新测试();
t、 特殊启动呼叫(t);
t、 特殊的。开始()代码>我想你的问题是关于函数中的这个参数。尝试使用apply或call方法
test=function(){this.name='test';}
test.prototype.special={name:'special',start:function(){alert(this.name)}
var t=新测试();
t、 特殊启动呼叫(t);
t、 特殊的。开始()代码>
此
的值在调用时由函数的调用方式决定
您希望绑定到test
(实例),而不是test
(构造函数)
如果您不想进行特定的调用时间调整,而是将函数预绑定到test
实例,那么在您拥有一个实例之前,这显然是不可能发生的,并且必须针对每个实例单独进行。因此,唯一的解决办法是:
function Test() {
this.special = {
start: (function () { ... }).bind(this)
};
}
也许您希望在原型上定义函数而不是内联函数;但是您仍然需要在构造函数中绑定它:
function Test() {
this.special = {
start: this._start.bind(this)
};
}
Test.prototype._start = function () { ... };
此
的值在调用时由函数的调用方式决定
您希望绑定到test
(实例),而不是test
(构造函数)
如果您不想进行特定的调用时间调整,而是将函数预绑定到test
实例,那么在您拥有一个实例之前,这显然是不可能发生的,并且必须针对每个实例单独进行。因此,唯一的解决办法是:
function Test() {
this.special = {
start: (function () { ... }).bind(this)
};
}
也许您希望在原型上定义函数而不是内联函数;但是您仍然需要在构造函数中绑定它:
function Test() {
this.special = {
start: this._start.bind(this)
};
}
Test.prototype._start = function () { ... };
根据对Kira答案的评论,补充已经给出的答案,您似乎对范围界定的工作方式有一个根本性的误解。Javascript有词法范围,意思是范围由源代码的结构定义,只有一个例外:this
此
是动态作用域,这意味着作用域由调用方定义。代码:
bar = 3
test = (foo) ->
foo + bar # bar can be seen, because its in an outer scope test can see
到目前为止还不错。现在让我们定义一个类:
class Test
constructor: (@foo) ->
getFoo: -> @foo
getFoo
部分相当于Test.prototype.getFoo=function…
。this
(@)的范围是getFoo
。getFoo
的调用程序确定this
:
obj1 = new Test 2
obj1.getFoo() # 2
fn = Test.prototype.getFoo;
fn()
fn
现在是一个独立的函数,而不是obj1
的方法。当我们调用fn
时,会发生以下两种情况之一。如果我们处于严格模式,它将抛出一个错误。因为我们在全局上下文中调用,所以getFoo
中的是未定义的。在非严格模式下,它将是全局窗口
,它将查找可能不存在的foo属性
我们可以通过绑定
、调用
、或应用
强制此
值
obj2 =
foo: 3
Test.prototype.getFoo.call(obj) # 3
这里我们使用它来“借用”测试类的方法。那么bind从何而来?假设我们的类有一个我们知道将在不同上下文中使用的方法,如事件处理程序:
class Test
constructor: (@foo) ->
@clickHandler = Test.prototype.clickHandler.bind this
clickHandler: (e) ->
console.log @foo
因为我们将把方法传递给.addEventListener
,这个上下文将消失,这意味着我们需要将它绑定到每个实例,这是我们在构造函数中所做的。要根据对Kira答案的评论添加到已经存在的答案中,您似乎对范围界定的工作方式有一个根本性的误解。Javascript有词法范围,意思是范围由源代码的结构定义,只有一个例外:this
此
是动态作用域,这意味着作用域由调用方定义。代码:
bar = 3
test = (foo) ->
foo + bar # bar can be seen, because its in an outer scope test can see
到目前为止还不错。现在让我们定义一个类:
class Test
constructor: (@foo) ->
getFoo: -> @foo
getFoo
部分相当于Test.prototype.getFoo=function…
。this
(@)的范围是getFoo
。getFoo
的调用程序确定this
:
obj1 = new Test 2
obj1.getFoo() # 2
fn = Test.prototype.getFoo;
fn()
fn
现在是一个独立的函数,而不是obj1
的方法。当我们调用fn
时,会发生以下两种情况之一。如果我们处于严格模式,它将抛出一个错误。因为我们在全局上下文中调用,所以getFoo
中的是未定义的。在非严格模式下,它将是全局窗口
,它将查找可能不存在的foo属性
我们可以通过绑定
、调用
、或应用
强制此
值
obj2 =
foo: 3
Test.prototype.getFoo.call(obj) # 3
这里我们使用它来“借用”测试类的方法。那么bind从何而来?假设我们的类有一个我们知道将在不同上下文中使用的方法,如事件处理程序:
class Test
constructor: (@foo) ->
@clickHandler = Test.prototype.clickHandler.bind this
clickHandler: (e) ->
console.log @foo
因为我们将把这个方法传递给.addEventListener
,这个上下文将消失,这意味着我们需要将它绑定到每个实例,就像我们在构造函数中做的那样。Thx Kira!但是现在我需要经常使用call或apply。我不能预绑定吗?prototype
中的@Dex变量由所有实例共享。如果将函数绑定到一个实例,则会破坏任何其他实例的绑定。也许你不应该使用prototype
@ZombieChowder,最好尽可能在链接上有属性。这里有Function.bind方法,而不是调用test.special.start(),你可以像test.start()@Kira一样调用bind
方法就是我说的,它会破坏所有其他函数