oop Class 的行为类似于构造函数参数类型

oop Class that behaves like the constructor parameter type

我希望能够创建一个看起来像传递给它的对象的 class,并向该对象添加新方法。

这是我目前的情况:

Node = function(data) {
  Node = data;
  Node.constructor.prototype = new data.constructor();
  Node.constructor.prototype.testProp = "Hello!";
  return Node;
};

node = Node('abc');
console.log(node); // abc
console.log(node.testProp); // Hello!
var testArray = [];
testArray.push(node);
console.log(testArray); // ['abc']

这个实现有什么问题?

节点 class 在此示例中看起来像一个字符串,但每个字符串现在都有一个 testProp 属性。

console.log(node.testProp) // 'Hello!'
console.log("something".testProp) // 'Hello!'

我的问题:

我应该如何实现一个 class,它的行为类似于在构造函数中传递的对象,而不影响同一 class 的所有其他对象?

为什么?

我问这个的原因是我希望元素数据 (String, Number, Array, Object, etc) 无需使用任何方法或道具即可访问例如 console.log(Node.value);,而我只想使用 console.log(Node);

谢谢!

以下不适用于基本类型(如字符串和数字)但适用于对象:

node = function(data) {//do not capitalize non constructor functions
  ret = Object.create(data);
  ret.testProp = "Hello!";
  return ret;
};

var proto = {name:'hello'};
test = node(proto);
console.log(test); //{testProp: "Hello!", name: "hello"}
console.log(test.testProp); // Hello!

请注意,如果你改变原型,你就会改变测试:

proto.name='changed';
console.log(test);//{testProp: "Hello!", name: "change"}

getter 和 setter 全局

此解决方案消除了对“.”的需要。但它只适用于全局变量。

var test = {value: "Hello World!"};

Object.defineProperty(window,'node_a', {
  get: function() {return test.value;},
  set: function(newValue) {test.value = newValue;},
  enumerable: true,
  configurable: true
});

function nodeValue() {
  console.log(node_a);
  node_a = "Foo Bar";
  console.log('test.value=' + test.value);
  console.log(node_a);
}

nodeValue();

输出:

Hello World!
test.value=Foo Bar
Foo Bar

toString 和 valueOf

您可以通过创建 toString 和 valueOf 函数将对象转换为字符串或数字。这会让你接近,但当它没有被字符串操作时,我们仍然对值进行序列化。

function Node(data) {
  this.data = data;
  this.test = 'world!';
}

Node.prototype.toString = function() {
  return this.data;
};

Node.prototype.valueOf = function() {
  return this.data;
}

var n = new Node('Hello');

console.log(n);
console.log(n+"");
console.log(n.test);

输出

 Node { data="Hello", test="world!", toString=function(), more...}
Hello
world!