2

这可能听起来有点不寻常,我以前从来不需要以这种方式使用方括号表示法,而且我绞尽脑汁想不出一种产生预期结果的方法。

我正在实现一个回调包装器来维护this将方法作为回调传递时的引用

例如

foo.prototype.wrap = function(name){
    var wrapper,
        self = this;

    wrapper = function(){
        self[name](arguments);
    };

    return wrapper;
};

// usage

foo.wrap('bar');

// executes foo.bar maintaining 'this' as a reference to foo 

我遇到的问题是 foo 有一些嵌套方法

例如

foo.bar.close();

我试图找出一种方法让 wrap 方法支持嵌套方法

例如

foo.wrap('bar.close')

// or

foo.wrap('bar','close');

因此,该foo.wrap函数需要动态添加与传入的长度或参数相对应的方括号。

例如

self[x][y][z](arguments);

我想不出办法来做到这一点。有任何想法吗 ?

我有一个偷偷摸摸的怀疑这是不可能的。

4

2 回答 2

6

我一定有一个你忘记一切的日子:)

虽然@NilColor 的答案是正确的,但我确实知道我只是没有戴上正确的帽子。

无论如何,我决定我仍然喜欢有一个包装器的想法,当你将它附加到你的对象时,它需要更少的特异性。并且不那么冗长。

所以我是按照我原来的思路写的,你可能会喜欢。

myObj.wrap = function(path, context){ 
    var wrapper,
        method = ( typeof path != 'string' && context )? path : this,
        context =  (typeof path === 'object' && context === undefined)? 
            path : (context || this);

    if (typeof path === 'string'){
        path = path.split('.');

        for ( var i = 0; i < path.length; i++ ){
            method = method[path[i]];
            if ( context === true  )
                context = ( i === path.length - 2 )? method : context; 
        };
    };

    wrapper = function(){
        method.apply(context, arguments);
    };

    return wrapper;
}

用法:

将任意数量的嵌套方法绑定到 myObj

    myObj.wrap('foo') //binds myObj.foo to myObj

// or

    myObj.wrap('foo.bar') //binds myObj.foo.bar to myObj

//or if myObj is a function

    myFunc.wrap() // binds myFunc to myFunc

将 myObj 的方法绑定到另一个对象

    myObj.wrap('foo.bar', someObj) //binds myObj.foo.bar to someObj

//or if myObj is a function

    myFunc.wrap(someObj) //Binds myFunc to someObj

将嵌套方法绑定到它的父级

    myObj.wrap('foo.bar', true) // binds myObj.foo.bar to myObj.foo

用作助手

    myObj.wrap(someFunc, someObj) //binds someFunc to someObj

如果您不是在方法绑定的上下文中寻找原始问题的答案。

myObj.getProps = function(path, context){
var context = context || this;
    path = path.split('.');


for ( var i = 0; i < path.length; i++ ){
            context = context[path[i]];
    };

    return context;
};

用法:

附加到对象或作为独立功能

获取属性

myObj.getProps('foo.bar') // returns mayObj.foo.bar

给它一个上下文对象

myObj.getProps('user.name', myAccounts) // returns myAccounts.user.name

将其用作独立功能替换

myObj.getProps = function(path,context){....}

function getProps(path,context){....}

笔记

如果将其用作独立函数,您需要记住它将从this. 因此,如果它是在全局范围内定义的,则需要提供完整路径。

例如

getProps('myObj.foo.bar')

您仍然可以使用上下文选择器来更改引用对象。

于 2011-08-22T22:37:18.133 回答
3

“绑定”的一般概念this是这样的:

function bind(method, context) {
      var args = Array.prototype.slice.call(arguments, 2);
      return function() {
            var a = args.concat(
                               Array.prototype.slice.call(arguments, 0));
            return method.apply(context, a);
      }
}

这样,您将获得对method带链接this( context) 的引用。这样,您可以像这样绑定嵌套方法:

> foo = {}
> foo.a = function(){console.log('a'); console.log(this)}
> bar = {bar: 'yeah'}
> f = bind(foo.a, bar)
> f()
-> a
-> {bar: 'yeah', __proto__: Object}

这是你要找的东西吗?

于 2011-08-22T11:50:42.500 回答