开发者

Checking if data is immutable

What is the quickest and cleanest way to test if a var holds immutable data (i.e. is string, number, boolean, null, undefined)?

E.g. When var test is mutable, the following is legal:

var test = {}; 
//the next 2 lines work because `test` has mutable data
test.someFun = function () { alert(this); };
test.someFun(); 

but when var test is immutable, it's illegal:

var test = "string"; 
//the next 2 lines are invalid, as `test` is a primitive
test.someFun = function () { alert(this); };
test.someFun(); 开发者_如何学JAVA


Just another short option:

function isPrimitive(value) {
  return Object(value) !== value;
}

How does it works:

If the value is a primitive value that is convertible to object, such as a Number, String or a Boolean, the strict equality operator will return true, since the Object constructor called as a function, will convert the value to a "wrapped object":

typeof 5;         // "number"
typeof Object(5); // "object", a wrapped primitive
5 === Object(5);  // false

If the value is a primitive not convertible to Object, such as null or undefined, the Object constructor will create a new empty object, returning true.

The last case, if value holds a reference to an object, the Object constructor will do nothing, and the strict equality operator will return false.


isMutable = function (test) {
     return test !== null && (typeof test == 'object' || typeof test == 'function');
}


var test = {};
if(test instanceof Object){
  test.someFun = function () { alert(this); };
  test.someFun(); 
}

jball pointed out the following:

For the instanceof check to work, the left-hand side object should be from the same scope as the right-hand side object. This is because even the common JavaScript objects have different copies in different scopes, i.e. window1.String !== window2.String. (Quote MDN)

Seems a valid point to me. So if you want to do this check across different scopes you will need to use the workaround:

var test = {};
if(test && (typeof test == 'object' || typeof test == 'function')){
  test.someFun = function () { alert(this); };
  test.someFun(); 
}

I would try to avoid the use of iframes though. The null check is needed because typeof(null) is equal to 'object'.

EDIT:

box9 and jball did some performance testing on all the methods proposed (+1 for that). I used Chrome, Firefox and Internet Explorer. The result are as expected. These two methods are the fastest. On Chrome and Firefox the typeofversion is the fastest. On Internet Explorer the instanceof version was the fastest. But the difference in speed between these two methods were minor. Personally I'd still go with the instanceof method if I could because it's cleaner.


Nice and short, just for fun (no && or ||s):

function isMutable(o) {
   return /(object)|(function)/.test(typeof(o||0));
}


Why don't you try if you're not sure?

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜