将javascript对象与`undefined`属性进行比较?

时间:2016-06-23 03:00:29

标签: javascript node.js mocha

lodash / underscore .isEqual(o1,o2)assert.deepEqual(o1,o2)应如何处理undefined值的对象?我想要一个在这种情况下返回true的deepEquals:

 var left = {a: true, b: undefined};
 var right = {a: true};
 assert(_.isEqual(left, right))   // returns false

或者,有没有办法测试属性b是否定义为undefined而不是仅仅定义?

 typeof left.b //  "undefined"
 typeof right.b // "undefined

 left.b === undefined  // true
 right.b === undefined // true

现在我正在使用这个来获取权宜之计,但怀疑它会产生假阴性:

var isEqual = function(o1, o2) { return JSON.stringify(o1) === JSON.stringify(o2)}

How to check for "undefined" in JavaScript?

3 个答案:

答案 0 :(得分:3)

  

或者,有没有办法测试属性b是否定义为未定义而不是仅仅定义?

是的,有很多方法可以区分这些情况。

 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles     Button1.Click
    Dim cmd As ADODB.Command
    Dim Rs As ADODB.Recordset
    Dim prm As ADODB.Parameter
    Dim db As New ADODB.Connection
    Dim PromoRejectDesc As String = ""

    db.ConnectionString = "Provider=SQLNCLI11;UID=user;Pwd=password;Database=POSData;Server=localhost;DataCompatibility=80;MARS Connection=True"

    db.Open()

    cmd = New ADODB.Command
    cmd.ActiveConnection = db
    cmd.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
    cmd.CommandText = "DBO.proc_PromoRejectingFactors"

    prm = cmd.CreateParameter("@CustID", ADODB.DataTypeEnum.adInteger, ADODB.ParameterDirectionEnum.adParamInput)
    prm.Value = 1050009326
    cmd.Parameters.Append(prm)
    prm = cmd.CreateParameter("@BranchID", ADODB.DataTypeEnum.adInteger, ADODB.ParameterDirectionEnum.adParamInput)
    prm.Value = 101
    cmd.Parameters.Append(prm)
    prm = cmd.CreateParameter("@FulfillmentChannel", ADODB.DataTypeEnum.adInteger, ADODB.ParameterDirectionEnum.adParamInput)
    prm.Value = 1
    cmd.Parameters.Append(prm)
    prm = cmd.CreateParameter("@Tender", ADODB.DataTypeEnum.adInteger, ADODB.ParameterDirectionEnum.adParamInput)
    prm.Value = 0
    cmd.Parameters.Append(prm)

    prm = cmd.CreateParameter("@CreditCard", ADODB.DataTypeEnum.adInteger, ADODB.ParameterDirectionEnum.adParamInput)
    prm.Value = -1
    cmd.Parameters.Append(prm)

    prm = cmd.CreateParameter("@ExcludePromo", ADODB.DataTypeEnum.adVarChar, ADODB.ParameterDirectionEnum.adParamInput, 1000)
    prm.Value = ""
    cmd.Parameters.Append(prm)

    prm = cmd.CreateParameter("@PromoRejectDesc", ADODB.DataTypeEnum.adLongVarChar, ADODB.ParameterDirectionEnum.adParamOutput, 9999)
    cmd.Parameters.Append(prm)

    Rs = cmd.Execute
    If Rs.State = 1 Then
        PromoRejectDesc = prm.Value
        MsgBox(PromoRejectDesc)
    End If
End Sub

查看带注释的来源,我认为这就足够了:

"b" in left; // true
"b" in right; // false

left.hasOwnProperty("b"); // true
right.hasOwnProperty("b"); // false

left.propertyIsEnumerable('b'); // true
right.propertyIsEnumerable('b'); // false

Object.keys(left).includes("b"); // true
Object.keys(right).includes("b"); // false

Object.getOwnPropertyNames(left).includes("b"); // true
Object.getOwnPropertyNames(right).includes("b"); // false

Reflect.ownKeys(left).includes("b"); // true
Reflect.ownKeys(right).includes("b"); // false

!!Object.getOwnPropertyDescriptor(left, 'b'); // true
!!Object.getOwnPropertyDescriptor(right, 'b'); // false

!!Reflect.getOwnPropertyDescriptor(left, 'b'); // true
!!Reflect.getOwnPropertyDescriptor(right, 'b'); // false

!!(o => {for(var p in o) if(p==='b') return 1; return 0;})(left); // true
!!(o => {for(var p in o) if(p==='b') return 1; return 0;})(right); // false

_.myEqual = function(a,b) {
  var keys = _.keys;
  _.keys = function(obj) { /* Hijack _.keys to filter out undefined properties */
    return _.filter(keys(obj), function(key){ return obj[key] !== void 0; });
  };
  var ret = _.isEqual(a,b); /* Call usual comparator, will use modified _.keys */
  _.keys = keys; /* Restore usual _.keys */
  return ret;
}
_.myEqual = function(a,b) {
  var keys = _.keys;
  _.keys = function(obj) {
    return _.filter(keys(obj), key => obj[key] !== void 0);
  };
  var ret = _.isEqual(a,b);
  _.keys = keys;
  return ret;
}
console.log(_.myEqual({a: true, b: undefined}, {a: true})); // true
console.log(_.myEqual({a: true, b: true}, {a: true})); // false

答案 1 :(得分:0)

left不等于right的原因是因为b是左边的属性,即使它未定义。

要检查某个对象上是否存在该属性,即使它未定义(如左侧示例所示),请使用 in 运算符:

"b" in left; // true
"b" in right; // false

Javascript 运算符:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in

快速检查属性是否存在且未定义的快速函数:

function propertyExistsAndIsUndefined(object, property) {
    return property in object && typeof object[property] === "undefined";
}

答案 2 :(得分:0)

这将删除未定义并保留assert.deepEqual_.isEqual的其他所需属性,如对属性顺序不敏感:

assert.jsonEqual = function(a, b) { return deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b))) }