将自定义 JavaScript 函数添加到方法调用链中的本机方法
A native way of adding custom JavaScript functions into a method-calls chain
我想知道是否有本地方法可以做到这一点:
Object.prototype.chain = function(f) { return f.call(this) }
function fun1() {
doSomethingWithObject(this)
return this
}
function fun2() {
doSomethingElse(this)
return this
}
someObject
.method1('something')
.method2()
.chain(checkSomething() ? fun1 : fun2)
.method3()
但是我不想改变Object
的原型。有没有办法在不修改 Objects
的原型或我使用的其他构造函数(并且不是
的开发者)的情况下做到这一点
编辑:
感觉自己解释的不是很好,补充一下吧:
我想做的是使用一些我没有定义的API。 someObject
定义如下,带有可链接的方法:
var someObject = {
method1: function(val) {
// do something
return this
},
method2: function() {
// do something
return this
},
method3: function() {
// do something
return this
}
}
现在假设我无法更改此代码,因为此对象来自库,所以我不想更改。然后,假设我想为更多不同的对象链接方法和一些自定义函数(请参阅我的第一个片段)。最简单的做法是将 chain
方法附加到 Object.prototype
.
但我认为这可能会导致将来发生冲突。我正在寻找一种在不接触原型的情况下做同样事情的方法。
老实说,我很惊讶没有答案。
有很多方法可以在本地引入链接。我喜欢用 revealing module pattern.
所以我创建了一个基本模型(继续将其放入您的 chrome Firefox 控制台)
var Dog = function(name) {
var self = this;
this.name = name;
var core = {
getName:function(){
return self.name;
}
};
this.movement = function(){ //this function will be exposed including its returned functions for chaining
console.log(self.name + " is getting restless... ");
var jump = function(){
console.log(self.name + " jumps around ");
return this //returns the movement scope
};
var run = function(){
console.log(self.name + " has decided to run");
return this //returns the movement scope
};
return {
jump:jump,
run:run
};
}
console.log("A Pup has been born, we shall call him... " + name);
return{
movement:self.movement //only .movement is exposed to the outside world
};
}
现在使用 var p = new Dog("doggyName");
创建一只新狗
现在,您可以链接函数。尝试:
p.movement().jump().run().jump().run();
您应该获得与每个函数对应的控制台记录文本。
通过在执行移动函数后返回 this 的范围,您公开了在该范围内返回的附加函数(请参阅代码中的注释)。然后可以将它们链接到当前函数的末尾,前提是它们在同一范围内。这允许您限定代码的特定部分。例如,对于这只狗,所有运动都限制在 self.movement
,你可以将所有进食限制在 self.eat
等等
Read up on the revealing module pattern。虽然这不是唯一的方法。
为了 "plug" 一个未绑定的函数到对象的方法链中,你可以将它分配给一个 属性 并调用它:
function fn() {
document.write('hi ');
return this;
}
someObj = {
meth1: function() {
document.write('meth1 ');
return this;
},
meth2: function() {
document.write('meth2 ');
return this;
}
}
someObj
.meth1()
[someObj._=fn, '_']()
.meth2()
如果你问我,这看起来不太漂亮。一个更具可读性的选项是动态添加 chain
方法,例如:
function chainable(obj) {
obj.chain = function(fn) {
return fn.call(this);
}
return obj;
}
chainable(someObj).meth1().chain(fn).meth2()
包装器将包装任何对象以使其与 "chaining" 兼容,并将添加另一个链方法,允许您插入外部函数并仍然获得链接。
检查这个例子:
function myObj() {
this.state = {
a: 1
};
this.method1 = function () {
console.log("1");
}
this.method2 = function () {
console.log("2");
}
this.method3 = function () {
console.log("3");
}
this.method4 = function () {
console.log(this.state);
}
}
function objectChainWrapper(obj) {
this.chain = function (fn) {
fn.call(obj);
return this;
}
for (var prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') {
this[prop] = (function (methodName) {
return function () {
obj[methodName].call(obj);
return this;
}
}(prop))
}
}
}
var obj = new myObj();
var wrapper = new objectChainWrapper(obj);
var chainMethod = function(){ console.log('chain') };
var chainMethodState = function(){ console.log(this.state) };
wrapper.method1().method2().chain(chainMethodState).method3().chain(chainMethod).method4();
我想知道是否有本地方法可以做到这一点:
Object.prototype.chain = function(f) { return f.call(this) }
function fun1() {
doSomethingWithObject(this)
return this
}
function fun2() {
doSomethingElse(this)
return this
}
someObject
.method1('something')
.method2()
.chain(checkSomething() ? fun1 : fun2)
.method3()
但是我不想改变Object
的原型。有没有办法在不修改 Objects
的原型或我使用的其他构造函数(并且不是
编辑:
感觉自己解释的不是很好,补充一下吧:
我想做的是使用一些我没有定义的API。 someObject
定义如下,带有可链接的方法:
var someObject = {
method1: function(val) {
// do something
return this
},
method2: function() {
// do something
return this
},
method3: function() {
// do something
return this
}
}
现在假设我无法更改此代码,因为此对象来自库,所以我不想更改。然后,假设我想为更多不同的对象链接方法和一些自定义函数(请参阅我的第一个片段)。最简单的做法是将 chain
方法附加到 Object.prototype
.
但我认为这可能会导致将来发生冲突。我正在寻找一种在不接触原型的情况下做同样事情的方法。
老实说,我很惊讶没有答案。
有很多方法可以在本地引入链接。我喜欢用 revealing module pattern.
所以我创建了一个基本模型(继续将其放入您的 chrome Firefox 控制台)
var Dog = function(name) {
var self = this;
this.name = name;
var core = {
getName:function(){
return self.name;
}
};
this.movement = function(){ //this function will be exposed including its returned functions for chaining
console.log(self.name + " is getting restless... ");
var jump = function(){
console.log(self.name + " jumps around ");
return this //returns the movement scope
};
var run = function(){
console.log(self.name + " has decided to run");
return this //returns the movement scope
};
return {
jump:jump,
run:run
};
}
console.log("A Pup has been born, we shall call him... " + name);
return{
movement:self.movement //only .movement is exposed to the outside world
};
}
现在使用 var p = new Dog("doggyName");
现在,您可以链接函数。尝试:
p.movement().jump().run().jump().run();
您应该获得与每个函数对应的控制台记录文本。
通过在执行移动函数后返回 this 的范围,您公开了在该范围内返回的附加函数(请参阅代码中的注释)。然后可以将它们链接到当前函数的末尾,前提是它们在同一范围内。这允许您限定代码的特定部分。例如,对于这只狗,所有运动都限制在 self.movement
,你可以将所有进食限制在 self.eat
等等
Read up on the revealing module pattern。虽然这不是唯一的方法。
为了 "plug" 一个未绑定的函数到对象的方法链中,你可以将它分配给一个 属性 并调用它:
function fn() {
document.write('hi ');
return this;
}
someObj = {
meth1: function() {
document.write('meth1 ');
return this;
},
meth2: function() {
document.write('meth2 ');
return this;
}
}
someObj
.meth1()
[someObj._=fn, '_']()
.meth2()
如果你问我,这看起来不太漂亮。一个更具可读性的选项是动态添加 chain
方法,例如:
function chainable(obj) {
obj.chain = function(fn) {
return fn.call(this);
}
return obj;
}
chainable(someObj).meth1().chain(fn).meth2()
包装器将包装任何对象以使其与 "chaining" 兼容,并将添加另一个链方法,允许您插入外部函数并仍然获得链接。
检查这个例子:
function myObj() {
this.state = {
a: 1
};
this.method1 = function () {
console.log("1");
}
this.method2 = function () {
console.log("2");
}
this.method3 = function () {
console.log("3");
}
this.method4 = function () {
console.log(this.state);
}
}
function objectChainWrapper(obj) {
this.chain = function (fn) {
fn.call(obj);
return this;
}
for (var prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') {
this[prop] = (function (methodName) {
return function () {
obj[methodName].call(obj);
return this;
}
}(prop))
}
}
}
var obj = new myObj();
var wrapper = new objectChainWrapper(obj);
var chainMethod = function(){ console.log('chain') };
var chainMethodState = function(){ console.log(this.state) };
wrapper.method1().method2().chain(chainMethodState).method3().chain(chainMethod).method4();