开发者

How to understand if (name in {}) in javascript?

开发者 https://www.devze.com 2023-01-31 23:42 出处:网络
I encounter a js function snippet, list as follows each = function(obj, fun) { if (typeof fun != \"function\") {

I encounter a js function snippet, list as follows

each = function(obj, fun) {
    if (typeof fun != "function") {
        return obj
    }
    if (obj) {
        var return_value;
        if (obj.length === undefined) {
            for (var name in obj) {
                if (name in {}) { // how to undertand this line, what's purpose?
                    continue
                }
                return_value = fun.call(obj[name], obj[name], name);
                if (return_value == "break") {
                    break
                }
            }
        } else {
            for (var i = 0,
            length = obj.length; i < length; i++) {
   开发者_StackOverflow             return_value = fun.call(obj[i], obj[i], i);
                if (return_value == "break") {
                    break
                }
            }
        }
    }
    return obj
};

Thanks for your answer:)


What it's doing is seeing if that property name exists in a blank object. So for instance, it will filter out toString (on implementations that aren't buggy about toString and in; IE is).

It may be an attempt to work around people adding things to the Object.prototype (which is a very, very bad idea). For instance:

Object.prototype.foo = "bar";    // <== VERY BAD IDEA
alert({}.foo); // alerts "bar"

function Thingy(a, b) {
    this.a = a;
    this.b = b;
}
Thingy.prototype.x = 42;

var t = new Thingy(1, 2);

If I want to copy t, including its inherited x property from Thingy but not including the foo property it inherits from Object, I could use that if (name in {}) to skip those.

Mind you, it's not a very smart way to do that, as it will fail if I do this:

var t = new Thingy(1, 2);
t.foo = "charlie";

Now t has its own foo, which presumably I would have wanted to copy.

A more thorough check would be:

dest = {};
blank = {}; // No need to recreate it on every iteration
for (name in src) {
    if (src.hasOwnProperty(name) || !(name in blank)) {
        dest[name] = src[name];
    }
}

That will only filter out ones that are inherited, or at least might be inherited, from Object. But even that's flawed; what if it inherits a value for the property, but not the value from Object (e.g., something in the middle — Thingy perhaps — has overridden Object's default)?

So you may want to refactor this code you've inherited, probably in terms of using hasOwnProperty and making sure that nothing anywhere in your application puts things on Object.prototype.


The in operator returns true if there is a property in the second operand with the identifier of the first operant, and false otherwise. So name in {} checks whether there is a property with the name of the value of name.

This probably seems odd as {} does not seem to have any properties. But a plain object inherits some the properties from Object.prototype. So "toString" in {} returns true as there is Object.prototype.toString. There is also the hasOwnProperty method inherited from Object.prototype.hasOwnProperty that can be used instead.


In is a special operator that returns true if the specified property is in the specified object.

From https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special_Operators/in_Operator

Every object, including {}, inherits properties from Object.prototype. The if here makes the loop continue if name is one of those inherited properties.

Example: console.log('toString' in {}); logs true. console.log('customProperty' in {}); logs false.

0

精彩评论

暂无评论...
验证码 换一张
取 消