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)}
答案 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)))
}