uni-app instanceof Array 在某种情况下出错

发布于 1周前 作者 h691938207 来自 Uni-App

uni-app instanceof Array 在某种情况下出错

开发环境 版本号 项目创建方式
Windows win10 HBuilderX

操作步骤:

预期结果:

实际结果:

bug描述:

对数组进行判断,在某些情况下出现不准确的现象; 如下图1: 对象res是通过ajax返回来的object中的一个属性,其本身也应该是数组。但是通过获取构造函数“constructor”后于Array比较的出 false的结论。 定义对象 a 为一个数组,遍历res后,变元素push给a,同样方式判断a,它就是一个数组。

但是 打印 res.constructor 和 a.constructor 都的出结果是“function Array() { [native code] }”,但是res.constructor === Array 结果为false,而a.constructor === Array 则为 true;

图2: 图2是res的结构,以及来源。“res”来源于拦截器中"data"对象中的"data"属性


2 回复

这就涉及到了内存地址不同导致的比较结果不同了。 uni对象和你本地定义的变量存在于不同的地方 首先两个数组对象直接打印的contructor当然是为Function Array.这是毋庸置疑的。 然而:强等于===比较的一般是内存的地址,本地和服务器的数组对象的constructor都各有自己的内存地址 你在res里面获取到数组示例,实际上是一个新的实例(经过序列化与反序列化处理之后), 因为res是在uni.request()方法那里构造出来的 所以res的constructor的内存地址指向的是uni的同一环境下的内存地址(假设为0000fff 而arr则是你本地另外一个内存环境内存地址(假设为0000fee 总结:这两个对象的constructor的内存地址是不同的。
const arr = [1];
console.log(arr.constructor === Array);// 0000fff === 0000fff 两个相等
console.log(arr.constructor);//function Array √

//res为服务器获取过来的数组对象
console.log(res.constructor === Array);// 0000fee === 0000fff 两个不相等
console.log(res.constructor);//function Array √ 也就是说 res只有在服务器本地执行res.constructor===Array输出才为true


uni-app 中,instanceof Array 在某些情况下可能会出错,尤其是在跨页面或跨组件传递数据时。这是因为 uni-app 的页面和组件之间的数据传递是通过序列化和反序列化进行的,这可能会导致对象的原型链丢失,从而导致 instanceof 检查失败。

常见问题场景

  1. 跨页面传递数组:当你从一个页面传递一个数组到另一个页面时,uni-app 会将数组序列化为 JSON 字符串,然后在目标页面反序列化。反序列化后的数组可能不再继承自 Array 的原型链,因此 instanceof Array 会返回 false

  2. 跨组件传递数组:类似地,当你在父组件和子组件之间传递数组时,uni-app 也可能会对数组进行序列化和反序列化,导致 instanceof Array 检查失败。

解决方案

  1. 使用 Array.isArrayArray.isArray 是一个更可靠的方法来检查一个对象是否是数组,因为它不依赖于原型链。

    if (Array.isArray(myArray)) {
        console.log('This is an array');
    } else {
        console.log('This is not an array');
    }
  2. 避免跨页面/组件传递复杂对象:如果可能,尽量避免在页面或组件之间传递复杂的对象。可以通过 Vuex 或全局变量来共享数据,这样可以避免序列化和反序列化的问题。

  3. 手动恢复原型链:如果你确实需要跨页面或组件传递数组,并且需要保持原型链,可以在目标页面或组件中手动恢复原型链。

    myArray.__proto__ = Array.prototype;

    但这种方法并不推荐,因为它可能会引入其他问题。

示例代码

// 页面A
let myArray = [1, 2, 3];
uni.navigateTo({
    url: '/pages/pageB?data=' + JSON.stringify(myArray)
});

// 页面B
onLoad(options) {
    let myArray = JSON.parse(options.data);
    if (Array.isArray(myArray)) {
        console.log('This is an array');
    } else {
        console.log('This is not an array');
    }
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!