3

I have question about native javascript calling.

i have a class:

x = function(arr) { this.arr = arr; return this; }
x.prototype.toArray = function() {
       return this.arr;
};
x.prototype.test = function() { alert('but i m object too!'); };

when i calling:

var test = new x(['a','b','c']);

alert(test[0]);

alert(test.test());

need to get result 'a' and 'but i m object too!' dialogs.

I want to use this feature as syntax sugar like uses jquery in core when returning DOM Elements after using selector as array. How to implement that?

UPDATE:

Thank for answer, but i need proofs in jquery code blob on github.

4
  • Do you want your object to be like an array or "inherit" all the methods that an array has? Commented Dec 11, 2013 at 2:58
  • 1
    @Jack My guess is like an array. Like how you can get the DOM element from a jQuery object using $('selector')[0] Commented Dec 11, 2013 at 3:00
  • Another way, i think.. i can extend Array object and write here my native methods from x.prototype... but it is "context dancing" :-) Commented Dec 11, 2013 at 3:14
  • 2
    "Thank for answer, but i need proofs in jquery code blob on github." No one is preventing you from looking at the source code: github.com/jquery/jquery/blob/master/src/core/init.js#L16. But if you want to do it exactly how jQuery does it, why did you asked the question in the first place? You could have just looked at the source code. Commented Dec 11, 2013 at 4:16

3 Answers 3

3

An array is nothing else than an object which treats numeric properties in a special way. You would have to copy every element of the array to the instance, using the index of the element as property name. You should also set the length attribute, to make it a true "array-like" object.

var X = function(arr) {
    for (var i = 0, l = arr.length; i < l; i++) {
        this[i] = arr[i];
    }
    this.length = arr.length;
};

var x = new X(['a', 'b', 'c']);
alert(x[0]);
Sign up to request clarification or add additional context in comments.

1 Comment

and jquery using that way?
1

Basically the jQuery prototype only has a length property and that makes it array-like; to "import" items into it, they must be copied one by one.

To perform this merge, they use the following function:

function merge(first, second) 
{
  var len = +second.length,
  j = 0,
  i = first.length;

  for ( ; j < len; j++ ) {
    first[ i++ ] = second[ j ];
  }

  first.length = i;

  return first;
}

Next, they define the constructor which can also be called as a function:

function x(arr)
{
    return new x.fn.init(arr);
}

The x.fn refers to a prototype from which the functions are inherited, as shown below:

x.fn = x.prototype = {
  constructor: x,
  test: function() {
    alert('yay');
  },
  init: function(arr) {
    return merge(this, arr);
  },
  length: 0
};

As you can see, your test() method is also there, together with an initialized length property. The only thing that remains is to bind the x.fn.init prototype to the above x.fn:

x.fn.init.prototype = x.fn;

With all that in place, the following code works as expected:

var y = x(['a', 'b', 'c']);

alert(y[0]); // shows 'a'
y.test(); // alerts 'yay'

1 Comment

Thanks for complete answer!
0

Why didn't you call toArray() that you have created?

Try:

x = function(arr) { this.arr = arr; }
x.prototype.toArray = function() {
       return this.arr;
};

var test = new x(['a','b','c']);

alert(test.toArray()[0]);

OR

x = function(arr) { this.arr = arr; }
x.prototype.toArray = function() {
       return this.arr;
};

var test = new x(['a','b','c']).toArray();

alert(test[0]);

1 Comment

This is still not what the OP wants.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.