将 Object.defineProperty 与 Angular 一起使用会引发 TypeError: Cannot assign to read only property (property)

Posted

技术标签:

【中文标题】将 Object.defineProperty 与 Angular 一起使用会引发 TypeError: Cannot assign to read only property (property) of #<Object>【英文标题】:Using Object.defineProperty with Angular throws TypeError: Cannot assign to read only property (property) of #<Object> 【发布时间】:2016-02-22 02:16:43 【问题描述】:

我的作用域上有一个对象,我希望该对象具有一些不可枚举的属性,但是在将可枚举描述符设置为 false 后,每当我尝试更改值时,我都会得到: "TypeError: Cannot assign to read only property (property) of #"

...即使我专门将它的可写和可配置描述符设置为 true。为什么会发生这种情况,我能做些什么来解决它? 在非严格模式下它不会抛出错误,它只是不做任何事情。 这应该可以正常工作:MDN ...

代码:

'use strict'
angular.module('app', []);

angular.module('app').controller('TestingCtrl',['$scope', function($scope)
  var that = this;  
  this.content =  contentArea:  ;
  
  function updateIsEmpty()
    that.content.contentArea.isEmpty = Object.keys(that.content.contentArea).length === 0;
    console.log(that.content.contentArea)
    console.log(Object.keys(that.content.contentArea));
  
  
  this.addSomethingToCA = function(val)
    that.content.contentArea.something = val;
    updateIsEmpty();
  ;
  this.removeSomethingFromCA = function()
    delete that.content.contentArea.something;
    updateIsEmpty();
  ;
  
  (function init()
    Object.defineProperty(that.content.contentArea, 'isEmpty', 
      enumerable: false
    , value: true
    , configurable: true
    , writeable: true
    );
   
  )();
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="TestingCtrl as testingctrl">
    <button ng-if="testingctrl.content.contentArea.isEmpty === true" 
            ng-click="testingctrl.addSomethingToCA('is weird')">add something</button>
    
    <button ng-click="testingctrl.removeSomethingFromCA()">remove something</button>
    <ul>
      <li ng-repeat="(key, val) in testingctrl.content.contentArea">
        key:  key  
        val:  val 
      </li>
    </ul>
  </div>
</div>

如果你运行上面的代码 sn-p 它会抛出: 类型错误:

 Cannot assign to read only property 'isEmpty' of #<Object>
    at updateIsEmpty (http://stacksnippets.net/js:35:38)
    at removeSomethingFromCA (http://stacksnippets.net/js:46:5)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js:161:190
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js:178:83
    at h.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js:101:273)
    at h.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js:102:48)
    at htmlButtonElement.<anonymous> (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js:178:65)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js:27:15
    at Array.forEach (native)
    at q (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js:7:255)

【问题讨论】:

【参考方案1】:

你有一个错字。您在属性描述符中的 writeable 键应该是 writable

【讨论】:

我。恨。我的。生活。有时。 @AndrewLuhring 哈哈,这发生在我们最好的人身上。 那种感觉,当您花 20 分钟制作小提琴,并花 1.5 小时搜索 Angular 代码以查看它们是否会覆盖任何范围内的描述符,结果却显示您拼错了一个东西。

以上是关于将 Object.defineProperty 与 Angular 一起使用会引发 TypeError: Cannot assign to read only property (property) 的主要内容,如果未能解决你的问题,请参考以下文章

利用object.defineProperty实现数据与视图绑定

Object.defineProperty 与 属性描述符

Object.defineProperty()

Object.defineProperty()

深入浅出Object.defineProperty()

Object.defineProperty方法