简体   繁体   English

Javascript方括号表示法多个动态属性

[英]Javascript Square Bracket Notation Multiple Dynamic Properties

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 outcome. 这可能听起来有点不寻常,我以前从来不需要用这种方式使用方括号表示法,并绞尽脑汁我想不出能够产生预期结果的方法。

I'm implementing a callback wrapper to maintain the reference of this when passing methods as callbacks 我执行一个回调的包装来维持的参考this传递方法作为回调时

eg 例如

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 我遇到的问题是foo有一些嵌套方法

eg 例如

foo.bar.close();

I'm trying to figure out a way to make the wrap method support nested methods 我试图想办法让wrap方法支持嵌套方法

eg 例如

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. 所以foo.wrap函数需要动态添加对应于传入的长度或参数的方括号。

eg 例如

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. 我怀疑这是不可能的。

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. 虽然@ NilColor的答案是正确的,但我确实知道它,我只是没有考虑正确的帽子。

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

    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的方法绑定到另一个对象

    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 . 如果使用它作为一个独立的功能,你需要记住,它会开始从范围看this So if it's defined in the global scope you need to provide full paths. 因此,如果它在全局范围内定义,则需要提供完整路径。

eg 例如

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: “绑定” 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 ). 这样,您将获得对链接thiscontext )的method的引用。 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? 这是你要找的东西吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM