Reputation: 116443
This is my code:
<div class='a'>
<div class='b'>Test</div>
</div>
and
$(['.b']).each(function () {
console.log($('.a').find(this).text()); // Expecting to print "Test"
});
I expect the console.log
to print Test
, but it doesn't! Is this a jQuery bug?
Upvotes: 3
Views: 840
Reputation: 126082
There are a few problems here.
$.each
, use the static version that iterates over generic objects or arrays.With both of those things said, there's stil an issue with using $.each
with an array containing primitive values. The following code exhibits the same problem you were seeing:
$.each([".b"], function () {
console.log($('.a').find(this).text()); // Expecting to print "Test"
});
Inside the callback function for .each
, this
is a String
object and not a string primitive. To understand this, we need to look at what .each
is doing under the hood:
for (; i < length;) {
if (callback.apply(object[i++], args) === false) { // <----
break;
}
}
The important bit is the call to apply
. According to the ECMAScript specification, when a primitive value is passed to apply
, the value's toObject
method is called:
If thisArg is null or undefined, the called function is passed the global object as the this value. Otherwise, the called function is passed ToObject(thisArg) as the this value.
This explains why your code was not working-- .find
expects a string primitive and not a String object.
This is why the documentation for $.each
actually mentions using this
with primitive values:
(The value can also be accessed through the this keyword, but Javascript will always wrap the this value as an Object even if it is a simple string or number value.).
Therefore the way to fix the problem with your code is to leverage the element
argument that's passed to the callback function:
$.each([".b"], function (_, item) {
console.log($('.a').find(item).text()); // Expecting to print "Test"
});
Upvotes: 5
Reputation: 20179
That's because you're on the dark side of JavaScript.
In JavaScript, this
is always made into an Object
so that typeof this === "object"
, no matter what this
was actually bound to. Even when a primitive string is bound to the this
context (which you'd expect to give typeof this === "string"
), this
is actually a String
object and typeof this === "object"
. Here's a more thorough explanation of this behaviour.
When iterating over arrays of non-objects, you should use the second argument of your callback function as value.
$(['.b']).each(function (index, value) {
console.log($('.a').find(value).text()); // Expecting to print "Test"
});
Upvotes: 0
Reputation: 171698
Don't use this
inside each when looping over an array. It works fine on objects or collection of elemnts but fails with arrays.
Use second argument of each
to access array element
$(['.b']).each(function (index, item) {
console.log($('.a').find(item).text()); // Expecting to print "Test"
});
DEMO http://jsfiddle.net/KbuZK/
Upvotes: 2