Javascript 检查数据是否不可变

Javascript 检查数据是否不可变,javascript,Javascript,测试var是否保存不可变数据(即字符串,数字,布尔值,空,未定义)的最快和最干净的方法是什么 例如,当var测试是可变的时,以下是合法的: var test = {}; //the next 2 lines work because `test` has mutable data test.someFun = function () { alert(this); }; test.someFun(); 但是当var test不可变时,它是非法的: var test = "string";

测试
var
是否保存不可变数据(即
字符串
数字
布尔值
未定义
)的最快和最干净的方法是什么

例如,当
var测试
是可变的时,以下是合法的:

var test = {}; 
//the next 2 lines work because `test` has mutable data
test.someFun = function () { alert(this); };
test.someFun(); 
但是当
var test
不可变时,它是非法的:

var test = "string"; 
//the next 2 lines are invalid, as `test` is a primitive
test.someFun = function () { alert(this); };
test.someFun(); 

如果你不确定,为什么不试试

var test = {};
if(test instanceof Object){
  test.someFun = function () { alert(this); };
  test.someFun(); 
}
贾巴尔指出:

要使“检查”实例生效,请 左侧对象应来自 与右侧的范围相同 对象这是因为即使是 常见的JavaScript对象具有 不同范围内的不同副本, i、 e.
window1.String!==window2.字符串。
(引述)

对我来说,这似乎是一个正确的观点。因此,如果要跨不同的作用域执行此检查,则需要使用变通方法:

var test = {};
if(test && (typeof test == 'object' || typeof test == 'function')){
  test.someFun = function () { alert(this); };
  test.someFun(); 
}
不过,我会尽量避免使用iframe。 由于
typeof(null)
等于
'object'
,因此需要进行null检查

编辑:
box9和jball对所有提出的方法都做了一些研究(+1)。我使用了Chrome、Firefox和Internet Explorer。结果如预期。这两种方法是最快的。在Chrome和Firefox上,
typeof
版本是最快的。在Internet Explorer上,
instanceof
版本是最快的。但这两种方法在速度上的差异很小。就我个人而言,如果可以的话,我仍然会使用
instanceof
方法,因为它更干净。

简洁,只是为了好玩(没有
&&
|
s):

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

只是另一个简短的选择:

function isPrimitive(value) {
  return Object(value) !== value;
}
它是如何工作的:

如果
是可转换为对象的基本值,例如
数字
字符串
布尔值
,则严格相等运算符将返回true,因为将值转换为“包装对象”:

如果值是不可转换为对象的原语,例如
null
undefined
,则对象构造函数将创建一个新的空对象,并返回true


最后一种情况是,如果
value
持有对一个对象的引用,那么
对象
构造函数将什么也不做,严格相等运算符将返回
false

这是我的想法,除了我只检查
test
而不是
test!==空
,例如
返回测试&&(测试类型='object'| |测试类型='function')
@galambalazs关键是
test
如果
null
未定义
,则将求值为false,然后
typeof
检查将处理其余情况。注意:我认为这在iframe情况下可能很脆弱-请参阅将if推广到函数,它还需要进行检查,以确保
test
未定义,因为
undefinedVariable instanceof Object
抛出异常。部分正确。当您执行此操作时,此测试有效:
var test=undefined试捕
区块。哦,是的。我没注意到他把“try”变成了一个代码片段。然而,对于如何检测对象是否不可变的问题,这并不是通用的解决方案。。。此外,您还可以避免可能出现的边缘情况或不一致性。+1似乎很有效-关于严格相等运算符的措辞有点混乱,这应该是不等式吗?+1很简单。同意@jball,只需将函数更改为
isMutable
,并使用
==
+1进行开箱思考。我不喜欢你正在创建一个额外的对象。就性能而言,这对我来说似乎是一个不利因素。正如预期的那样,速度较慢(),但对我来说非常有趣:PSure,这段代码每次调用它时都会创建一个RegExp对象(在大多数引擎中,它可能会创建)。顺便说一句,我看到一个
|
在那里;)@彭彭啊,你说得对,我怎么会错过呢。虽然很有趣。。。主要的性能问题不是创建regexp对象,而是执行
.test()
,至少在chromeIn上,如果有人想在给定的浏览器中比较以下解决方案的性能:
function isPrimitive(value) {
  return Object(value) !== value;
}
typeof 5;         // "number"
typeof Object(5); // "object", a wrapped primitive
5 === Object(5);  // false