创建对象后设置原型属性的可移植方法是什么?

What is the portable way of setting prototype property after an object is created?

本文关键字:可移植 方法 是什么 属性 设置 原型 创建对象      更新时间:2023-09-26

我有一个从JSON创建的JavaScript对象。我需要将它的prototype属性设置为不同的对象,因为JS5有getter和setter。下面是我需要的一个例子,在Chrome上工作:

function MyObj() { }
MyObj.prototype = { 
  get myProp : function () { return this._myProp; },
  set myProp : function (arg) { this._myProp = arg; }
}
... stuff ...
var instance = JSON.parse(result);
instance.constructor = MyObj;
instance.__proto__ = MyObj.prototype;

使用这段代码,我可以使用原型中定义的getter和setter获取和设置instance的属性。然而,这是不可移植的,不能在IE上工作,(也不是node,我认为)。

做这件事的合适和便携的方法是什么?

反过来想:

创建一个新的MyObj实例,然后复制instance的属性到它。或者给MyObj一个构造函数,当你提供一个参数:

function MyObj(instance) {
 if (instance) {
   //copy properties

这样你甚至可以做

var instance = new MyObj(JSON.parse(result));

您可以尝试使用JSON恢复函数。

function revive(json) {
  var m = new MyObj(), y;
  return JSON.parse(json, function(k, v){ 
    if (!y) y = this; 
    return k == "" ? m : this == y ? m[k] = v : v 
  });
}

调用revive('... a json string ...'),它将吐出一个MyObj的实例,其属性定义在JSON字符串中。

警告:只有当JSON对象中的第一项是原始值时,这才会起作用。如果在您的情况下这是不可能的,这里有一个相当难看的解决方案:

function revive(json) {
  var m = new MyObj(), c = json.charAt(0), y, a;
  if (c == '[') {
    a = json = '[0,' + json.substring(1);
  } else if (c == '{') {
    json = '{"@":0,' + json.substring(1);
  }
  return JSON.parse(json, function(k, v){ 
    if (!y) { y = this; return; } 
    return k == "" ? m : this == y ? m[a ? k - 1 : k] = v : v 
  });
}