检查数据是否不可变

jba*_*all 6 javascript

什么是测试如果最快和清晰的方式var保持不变的数据(即IS string,number,boolean,null,undefined)?

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

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

但是当var test它是不可变的时,它是非法的:

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

CMS*_*CMS 7

另一个简短的选择:

function isPrimitive(value) {
  return Object(value) !== value;
}
Run Code Online (Sandbox Code Playgroud)

它是如何工作的:

如果value是一个基本值,转换为对象,如Number,String或Boolean,全等运算符将返回true,因为Object作为函数调用构造函数,将值转换为一个"包装物":

typeof 5;         // "number"
typeof Object(5); // "object", a wrapped primitive
5 === Object(5);  // false
Run Code Online (Sandbox Code Playgroud)

如果值是不可转换为Object的基元,例如nullor undefined,则Object构造函数将创建一个新的空对象,返回true.

最后一种情况,如果value持有对象的引用,Object构造函数将不执行任何操作,并且将返回严格相等运算符false.


Jan*_*Jan 1

var test = {};
if(test instanceof Object){
  test.someFun = function () { alert(this); };
  test.someFun(); 
}
Run Code Online (Sandbox Code Playgroud)

jball 指出了以下几点:

为了使instanceof检查起作用,左侧对象应该与右侧对象来自同一范围。这是因为即使是常见的 JavaScript 对象在不同的​​范围内也有不同的副本,即window1.String !== window2.String. (引用MDN)

对我来说似乎是有道理的。因此,如果您想跨不同范围进行此检查,您将需要使用解决方法:

var test = {};
if(test && (typeof test == 'object' || typeof test == 'function')){
  test.someFun = function () { alert(this); };
  test.someFun(); 
}
Run Code Online (Sandbox Code Playgroud)

不过,我会尽量避免使用 iframe。需要空检查,因为typeof(null)等于'object'。

编辑:

box9 和 jball对所有建议的方法进行了一些性能测试(+1)。我使用 Chrome、Firefox 和 Internet Explorer。结果正如预期的那样。这两种方法是最快的。在 Chrome 和 Firefox 上,该typeof版本是最快的。在 Internet Explorer 上,该instanceof版本是最快的。但这两种方法之间的速度差异很小。就我个人而言,如果可以的话,我仍然会选择这种instanceof方法,因为它更干净。