【问题标题】:oop Class that behaves like the constructor parameter typeoop 行为类似于构造函数参数类型的类
【发布时间】:2015-05-21 23:58:39
【问题描述】:

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

这是我目前所拥有的:

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']

这个实现有什么问题?

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

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

我的问题:

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

为什么?

我问这个的原因是我希望元素数据 (String, Number, Array, Object, etc) 可以在不使用任何方法或道具的情况下访问,例如console.log(Node.value);,相反,我只想使用console.log(Node);

谢谢!

【问题讨论】:

  • 好吧,在您的示例中,您传递的是 primitive 值,而不是对象。您不能“扩展”原始值而不影响同一类型的所有原始值。如果您使用实际对象,您可能只想直接 将新属性分配给它,而不是它的原型。但我想我真的不明白“看起来像对象的类”是什么意思。是否要动态创建子类?
  • @FelixKling 感谢 Felix 的澄清,您是否看到任何解决方法可以使原始值的实现成为可能?
  • @FelixKling 我想要的是能够 console.log(node) 和输出例如是一个字符串,并且在数组中表现相同。
  • 如果您想控制如何将任何对象转换为原始值,您可以覆盖其toStringvalueOf 方法。有关示例,请参见 stackoverflow.com/questions/27989285/…
  • 这只是显示 DOM 元素的 HTML 表示的控制台。这是特定于浏览器的行为,与 JavaScript 或 jQuery 无关。这适用于每个 DOM 元素,只需尝试 console.log(document.body)

标签: javascript string oop constructor prototype


【解决方案1】:

全局的 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!

【讨论】:

  • 感谢您的帮助,但我希望能够使用 console.log(n) 来完成。
  • 你知道如何在 Node.js 中做到这一点吗?
  • @KauêGimenes 它可能适用于全局对象。尝试用全局替换窗口。
【解决方案2】:

以下内容不适用于原始类型(如字符串和数字),但适用于对象:

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"}

【讨论】:

    猜你喜欢
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    • 2010-12-05
    • 2012-09-22
    • 2015-11-05
    • 1970-01-01
    相关资源
    最近更新 更多