gpt4 book ai didi

Javascript绑定(bind)到对象

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:08:04 27 4
gpt4 key购买 nike

function Developer(skill) {
this.skill = skill;
this.says = function() {
alert(this.skill + ' rocks!');
}
}
var john = new Developer('Ruby');
var func = john.says;
func();

我尝试了这个例子,当我这样做时,我收到以下消息 undefined rocks! 而不是 Ruby rocks!。 你能解释一下这是为什么吗?

最佳答案

函数执行上下文和this关键字

JavaScript 函数 在调用时有一个执行上下文,因此 this 关键字绑定(bind)到调用它们的对象。如果您调用 john.says(),函数的执行上下文将有一个指向 johnthis 关键字。如果您改为将全局变量 func 分配给在对象 john 上找到的方法 says,则您已将执行上下文更改为全局对象。当您调用 func 函数时,this 取消对 window(或 undefined*)的引用,因为 window .skill 是未定义的, 会将该值强制转换为一个字符串以将其与字符串“rocks!”连接起来。

如何使用bind保证执行上下文

您可以改为将函数的副本绑定(bind)到一个对象(有效地锁定它的上下文引用):

var func = john.says.bind(john);

如何使用闭包保证执行上下文

或者,您可以通过在构造函数中使用闭包来关闭相关位:

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;
}

如何使用闭包保证值

您可以直接从方法中引用 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!');
}
}

如何使用 call 和 apply 在调用时保证执行上下文

最后的选择是在调用时使用您想要的上下文调用方法:

func.call(john /*, optional arguments... */);
func.apply(john /*, optional arguments as an array */);

如何使用原型(prototype)让动态执行上下文设置正确的this

如果我们想在对象实例或类型之间重用一个方法,但在调用时有正确的执行上下文,我们可以使用原型(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!")

更多阅读:

* "use strict"激活代表 JavaScript future 的特殊严格模式。当未设置上下文时,这种特殊的严格执行环境不会解析为全局对象,而是将其解析为适当范围的值 undefined

关于Javascript绑定(bind)到对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22928102/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com