最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

syntax - Javascript Square Bracket Notation Multiple Dynamic Properties - Stack Overflow

programmeradmin8浏览0评论

This may sound a bit unusual, I've never needed to use square bracket notation in this way before, and racking my brains I can't think of a way to produce the desired oute.

I'm implementing a callback wrapper to maintain the reference of this when passing methods as callbacks

e.g.

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 

The issue I'm having is that foo has some nested methods

e.g.

foo.bar.close();

I'm trying to figure out a way to make the wrap method support nested methods

e.g.

foo.wrap('bar.close')

// or

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

So the foo.wrap function would need to dynamically add the square brackets corresponding to the length or the arguments passed in.

e.g.

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

I can't think of a way to do this. Any ideas ?

I have a sneaking suspicion this isn't possible though.

This may sound a bit unusual, I've never needed to use square bracket notation in this way before, and racking my brains I can't think of a way to produce the desired oute.

I'm implementing a callback wrapper to maintain the reference of this when passing methods as callbacks

e.g.

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 

The issue I'm having is that foo has some nested methods

e.g.

foo.bar.close();

I'm trying to figure out a way to make the wrap method support nested methods

e.g.

foo.wrap('bar.close')

// or

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

So the foo.wrap function would need to dynamically add the square brackets corresponding to the length or the arguments passed in.

e.g.

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

I can't think of a way to do this. Any ideas ?

I have a sneaking suspicion this isn't possible though.

Share Improve this question edited Aug 15, 2017 at 23:28 Machavity 31.7k27 gold badges95 silver badges105 bronze badges asked Aug 22, 2011 at 11:38 AshHeskesAshHeskes 2,3241 gold badge21 silver badges27 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

I must be having one of those days where you forget everything :)

While @NilColor's answer is correct, and I did know it I just wasn't thinking with the correct hat on.

Anyway I decided that I still like the idea of having a wrapper that requires a bit less specificity when you attach it to your objects. And is a bit less verbose.

So I wrote it along with my original line of thinking, you might like it.

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;
}

usage:

Bind any number of nested methods to 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

Bind a method of myObj to another object

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

//or if myObj is a function

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

Bind a nested method to it's parent

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

Use as a helper

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

If you looking for an answer to the original question not in the context of method binding.

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;
};

Usage:

attach to an object or as a standalone function

Get the properties

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

Give it a context object

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

to use it as a standalone function replace

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

with

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

Note

If using it as a standalone function you will need to remember that it will start looking from the scope of this. So if it's defined in the global scope you need to provide full paths.

e.g.

getProps('myObj.foo.bar')

You can still use the context selector to change the reference object.

A general concept of "binding" this is something like 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);
      }
}

This way you'll get a reference to method with linked this (context). This way you can bind nested methods like this:

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

Is it something you are looking for?

发布评论

评论列表(0)

  1. 暂无评论