类型错误:无法添加属性 1,对象不可扩展↵ 在 Array.push (<anonymous>)
Posted
技术标签:
【中文标题】类型错误:无法添加属性 1,对象不可扩展↵ 在 Array.push (<anonymous>)【英文标题】:TypeError: Cannot add property 1, object is not extensible↵ at Array.push (<anonymous>) 【发布时间】:2019-02-28 17:14:42 【问题描述】:我正在尝试向数组添加一些数据,但出现不可扩展错误。
组件代码:
this._store.select(p => p.collection.workspaceCollectionPages).subscribe((data: CollectionPageDbModel[]) =>
if(data)
return data.map((collectionPageDbModel)=>
this.collectionPages.push(collectionPageDbModel) //Getting error on this line while pushing
);
我的数据变量中有四个对象,我试图将它们推送到 collectionPages 中,但推送时出现可扩展错误。
我需要添加更多数据的 collectionPage 数组
这个数据我需要推送
CollectionPageDbModel:
export class CollectionPageDbModel implements IDbModel
public id?: number;
public collection_version_id: number;
public user_id?: string;
public name: string;
public position?: number = 0;
public contents: string;
public created_at?: string;
public updated_at?: string;
public server_id?: any;
谁能帮我解决这个问题
【问题讨论】:
请将collectionPageDbModel 类添加到您的问题中collectionPages
之后会发生什么?在this._store.select(
之后
在将新对象推送到 collectionPages 时会抛出对象不可扩展错误
您是否在任何地方使用preventExtensions
或将this.collectionPages
对象传递给可能执行此操作的函数?即使在store.select
之后,由于 javascript 事件队列,这也会导致问题
为什么会有return
声明?我认为那里不需要这样做,因为您只是将对象推入内部。尝试删除return
,您可以将其用作其他选项,例如this.collectionPages = [...this.collectionPages, collectionPageDbModel]
【参考方案1】:
使用 Object.assign 方法复制对象并重试,
this.collectionPages = Object.assign([], this.collectionPages);
this.collectionPages.push(collectionPageDbModel);
【讨论】:
为什么复制对象可以解决问题?有没有 js6 解决方案? @AliSaberi 晚了,但我认为状态元素/属性应该是不可变的。您是否尝试过从那里改变数组的操作? @AliSaberi 我认为更多的 JS6 解决方案是:this.collectionPages = [...this.collectionPages, collectionPageDbModel]
【参考方案2】:
Daniel 提出的解决方案当然适用于这种情况。原因是每个 JS 对象都有的对象描述符。你可以通过调用Object.getOwnPropertyDescriptors(obj)
来检查它们,它也适用于数组,因为(几乎)所有东西都是一个对象。
问题中最可能使用的 NGRX 存储选择器使用 Object.defineProperties(obj)
修改对象描述符。这样做是为了防止在 Reducer 之外的 Store 中的数据发生任何突变(它也不会改变状态,只是创建一个新状态)。
一般情况下,您必须克隆要变异的对象:
import cloneDeep from 'lodash'
// ...
constructor(private store: Store<any>)
someMethod()
let someDataFromTheStore = cloneDeep(this.store.select(selectSomeData))
someDataFromTheStore.myArray.push('...')
Object.assign
和 cloneDeep
都不会将描述符传输到新副本。
Object.getOwnPropertyDescriptors
Object.defineProperties
【讨论】:
【参考方案3】:这个工作,
if(data)
const result = data.map((collectionPageDbModel)=>
this.collectionPages.push(collectionPageDbModel) //Getting error on this line while pushing
);
return result
// incase of async call this one will work fine
// return Promise.all(result)
【讨论】:
【参考方案4】:尝试将数据推送到数组时,我遇到了类似的错误警告。
我的解决方案是使用扩展运算符而不是 push
:
let myarray: any = [];
const data =
answers: [],
score: 24,
ctime: '',
;
myarray = [...myarray, data]; // used this instead of push
【讨论】:
以上是关于类型错误:无法添加属性 1,对象不可扩展↵ 在 Array.push (<anonymous>)的主要内容,如果未能解决你的问题,请参考以下文章
代码在 codeSandbox 中运行良好,但在 IDE 中显示错误为“无法定义属性“电子邮件”:对象不可扩展”
未捕获的类型错误:无法读取未定义的属性“internalId”(在扩展时对节点进行排序)
未捕获的类型错误:无法读取 chrome 扩展中未定义的属性“本地”