虽然之前已经提出过这个问题而且很多人已经回答了这个问题,但我的问题是严格关于新创建函数的原型。
如果您阅读了这段代码,您就会明白它只是有效。同样在codepen。
// main object
var Foo = {};
// main methods
Foo.render = {}; // the Render function to populate later
Foo.start = function(el,ops){
return new Actions(el,ops);
}
// secondary/utility functions
var Actions = function(el,ops){
this.el = document.querySelector(el);
this.ops = ops || {};
this.prepare(); // this builds the Foo.render functions
for (var p in this.ops){
Foo.render[p](this);
}
};
// Action methods
Actions.prototype.prepare = function(){
for (var p in this.ops) {
Foo.render[p] = function(that){ // or r[p]
that.el.style[p] = that.ops[p] + 'px';
}
}
}
// init
var action = new Foo.start('div',{left:15})
// check
console.log(Foo.render['left'].prototype);
<div></div>
问题是新创建的函数Foo.render['left']
的原型是这样的Foo.render.(anonymous function) {}
而不是像Foo.render.left() {}
或类似的东西,我遇到了一些性能损失,因为我是无法快速访问新创建的函数原型。
有人可以说明如何调整.prepare()
函数以在Foo
范围内创建准确/可访问(我无法选择正确的单词)原型函数吗?
谢谢。
答案 0 :(得分:1)
您需要在额外的闭包范围内捕获p
的值。另外,我建议避免覆盖已有的方法。
Actions.prototype.prepare = function() {
for (var p in this.ops) {
if (!(p in Foo.render)) {
Foo.render[p] = (function(prop) {
return function(that) {
that.el.style[prop] = that.ops[prop] + 'px';
};
}(p));
}
}
};
或
Actions.prototype.prepare = function() {
for (var p in this.ops) {
(function() {
var prop = p;
if (!(prop in Foo.render)) {
Foo.render[prop] = function(that) {
that.el.style[prop] = that.ops[prop] + 'px';
};
}
}());
}
}
答案 1 :(得分:0)
我想我找到了一种让它更好用的方法。以下应该做,但我仍然很想知道是否有更好的解决方案。
// main object
var Foo = {};
// main methods
Foo.render = {}; // the Render function to populate later
Foo.start = function(el,ops){
return new Actions(el,ops);
}
// secondary/utility functions
var Actions = function(el,ops){
this.el = document.querySelector(el);
this.ops = ops || {};
this.prepare(); // this builds the Foo.render functions
for (var p in this.ops){
Foo.render[p](this);
}
};
// Action methods
Actions.prototype.prepare = function(){
for (var p in this.ops) {
Foo.render[p] = (function(){ // or r[p]
return function(that){
that.el.style[p] = that.ops[p] + 'px';
}
})();
}
};
// init
var action = new Foo.start('div',{left:15})
// check
console.log(Foo.render['left'].prototype);
更新:我认为我找到了一种方法来消除其中一个闭包,基本上使用p
作为函数的第二个属性,就像Foo.render[p] = function(that,p){}
这样我们去了:
// main object
var Foo = {};
// main methods
Foo.render = {}; // the Render function to populate later
Foo.start = function(el,ops){
return new Actions(el,ops);
}
// secondary/utility functions
var Actions = function(el,ops){
this.el = document.querySelector(el);
this.ops = ops || {};
this.prepare(); // this builds the Foo.render functions
for (var p in this.ops){
Foo.render[p](this,p); // we include p here
}
};
// Action methods
Actions.prototype.prepare = function(){
for (var p in this.ops) {
Foo.render[p] = function(that,p){ // we also include p here
that.el.style[p] = that.ops[p] + 'px';
};
}
};
// init
var action = new Foo.start('div',{left:15})
// check
console.log(Foo.render['left'].prototype);
<div></div>
这消除了额外的闭包,使函数更接近主线程的范围。欢迎对此更新发表任何评论。