[英]Javascript extend arguments passing
var Model = function(client, collection) {
this.client = client;
this.collection = collection;
};
Model.prototype = {
constructor: Model,
getClient: function(callback) {
this.client.open(callback);
},
getCollection: function(callback) {
var self = this;
this.getClient(function(error, client) {
client.collection(self.collection, callback);
});
},
extend: function(key, fn) {
var self = this;
this[key] = function() {
fn.call(self); // A
};
}
};
我想要实现的是我可以“扩展”模型的功能。
var userModel = new Model(client, 'users');
userModel.extend('create', function(data, callback) {
this.getCollection(function(error, collection) {
collection.insert(data, { safe: true }, function(error, doc) {
callback.call(doc);
});
});
});
userModel.create({ fullName: 'Thomas Anderson' }, function() {
console.log(this); // { _id: '123456789012345678901234', fullName: 'Thomas Anderson' }
});
在A处,我必须进行参数传递,自定义“创建”函数(数据和回调)的参数计数是可变的。
这有可能吗?如果可以的话怎么样?
是的! 你想使用.apply
在法.call
方法。 两者都应用上下文,但.apply
方法为参数采用数组 - 或者参数集合本身!
extend: function(key, fn) {
var self = this;
this[key] = function() {
fn.apply(self,arguments); // the special arguments variable is array-like
};
}
this[key] = function() {
fn.apply(self, arguments);
};
在@zetlen注释之后还有一件事,函数的范围(this)是函数调用的最后一个点,在这种情况下:
userModel.create();
函数的“this”变量将是“userModel”。
因此,只要您使用“modelname.functionName()”调用它,就不需要传递self:
extend: function(key, f) {
this[key] = f;
}
(要不就)
userModel.someMethod = function() { ... };
然后,当您调用modelkey时,您将直接将参数传递给函数,并且您将拥有所需的范围。
var userModel = new Model(...);
userModel.extend('hi', function(arg) {
this === userModel;
arg === 42;
});
userModel.hi(42);
看看这个小提琴看到它: http : //jsfiddle.net/NcLQB/1/
但是请记住,如果你拿出模型的功能,它将不再具有范围,在你这样做的情况下,你最好继续像你的代码片段一样。
var funct = userModel.hi;
funct(); // this === global!!!
// OR
// When the event is fired the scope isn't userModel
otherThing.on('someEvent', userModel.hi);
除非您有任何隐藏的原因在原型中创建extend
方法并强制执行范围,否则您只需将方法分配给创建的实例:
var userModel = new Model(client, 'users');
userModel.create = function(data, callback) {
this.getCollection(function(error, collection) {
collection.insert(data, { safe: true }, function(error, doc) {
callback.call(doc);
});
});
});
它会更快,更清晰,你不必担心通过另一个函数传递参数。
通过封装来实现范围(或上下文)并不总是一件好事,因为您限制了语言的动态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.