根据以下代码,我在访问原型中的this
变量时遇到了一个小问题。
var MyClass = function(number) {
this.number = number || 4;
};
MyClass.prototype = {
run: function() {
//direct access to object
console.log(this.number);
//access to object with the "self" object
var self = this;
setTimeout(function() {
console.log(self.number);
}, 1000);
//access to object with the "self" object as a parameter
this.events.test_a(self);
//here is the problem
this.events.test_b();
},
events: {
test_a: function(self) {
//access to object with the "self" object as a parameter
console.log(self.number);
},
test_b: function() {
console.log(this.number); // ? The problem
}
}
};
//----
var myClass = new MyClass(110);
myClass.run();
有什么方法可以访问this
对象并具有如下所示的结构?
myClass.events.test_b();
我需要这个?,而不必使用我刚刚创建的实例,如下所示:?
myClass.events.test_a(myClass);
答案 0 :(得分:3)
通常,最好避免以这种方式设计结构。
但是您可以通过在构造函数中绑定events
函数来做到这一点,这意味着创建事件对象的“拥有”副本。请参见此最小更改版本中的***
条评论:
// NOTE: Sticking to ES5 as the OP seems to be doing that
var MyClass = function(number) {
this.number = number || 4;
// *** Bind the functions on `this.events` to `this`
var self = this;
var events = self.events;
self.events = {};
Object.keys(events).forEach(function(key) {
if (typeof events[key] === "function") {
self.events[key] = events[key].bind(self);
}
});
};
// I've added the "name" parameter that's being passed around
// so we can be sure that the results for multiple
// instances are correct
MyClass.prototype = {
constructor: MyClass, // *** Don't break prototype.constructor
run: function(name) {
//direct access to object
console.log(name, "Direct access in object:", this.number);
//access to object with the "self" object
var self = this;
setTimeout(function() {
console.log(name, "In setTimeout callback:", self.number);
}, 1000);
//access to object with the "self" object as a parameter
this.events.test_a(name, self);
//here is the problem
this.events.test_b(name);
},
events: {
test_a: function(name, self) {
//access to object with the "self" object as a parameter
console.log(name, "In test_a:", self.number);
},
test_b: function(name) {
console.log(name, "In test_b:", this.number); // ? Not a problem anymore
}
}
};
//----
var mc1 = new MyClass(110);
var mc2 = new MyClass(220);
setTimeout(function() {
mc1.run("mc1");
}, 1000);
setTimeout(function() {
mc2.run("mc2");
}, 2000);
.as-console-wrapper {
max-height: 100% !important;
}
旁注:请参阅我添加到要分配给prototype
的对象的这一行:
constructor: MyClass, // *** Don't break prototype.constructor
默认情况下,函数上的prototype
对象具有指向该函数的constructor
属性,因此最好这样做。
答案 1 :(得分:2)
您可以通过以下方式传递<TextField
id="standard-full-width"
label="Password"
style={{ margin: 8 }}
fullWidth
margin="normal"
placeholder="*******"
/>
实例的上下文来调用events.test_b
:
MyClass
this.events.test_b.call(this);
答案 2 :(得分:1)
我建议使用现代JS和箭头功能。
也许还有向下转换的编译器(如有必要)
class MyClass {
constructor(number = 4) {
this.number = number;
}
run() {
//direct access to object
console.log("run", this.number);
// no need for "self"
setTimeout(() => {
console.log("setTimeout", this.number);
}, 1000);
//access to object with the "this" object as a parameter
this.events.test_a(this);
//here is the problem
this.events.test_b();
}
events = {
test_a: (self) => {
//access to object with the "self" object as a parameter
console.log("test_a", self.number);
},
test_b: () => {
console.log("test_b", this.number); // ? The problem
}
}
};
//----
var a = new MyClass(110);
a.run();
console.log("---");
var b = new MyClass(42);
b.run();
console.log("---");
Typescript也可能是替代方案,因为它包含了转译器。
imo。仅仅因为目标受众的一部分仍然使用过时的浏览器并且需要支持它们,所以编写过时的代码是不合理的。是的,我也有使用IE10的客户端,并且需要支持该浏览器。