【发布时间】:2011-09-15 16:34:13
【问题描述】:
每当我尝试将对象BaseNet 添加到IPv4Address.prototype 时都会出错。错误:
TypeError: 无法读取未定义的属性“ipInt”
只是没有意义。当我将对象复制到原型时,它的行为就像实际上正在执行 getter。有没有办法复制这个并且不会出现这样的错误?
var _s = require('underscore')
var BaseNet = {
get network(){
return new IPv4Address((this.ipInt & this.netmask.ipInt) >>> 0);
},
}
function IPv4Address (address){
this.ipInt = address
this.netmask = {}
this.netmask.ipInt = 255
}
_s.extend(IPv4Address.prototype,BaseNet)
//also fails with generic extend:
function extend(destination, source) {
for (var k in source) {
if (source.hasOwnProperty(k)) {
destination[k] = source[k];
}
}
return destination;
}
extend(IPv4Address.prototype,BaseNet)
首次编辑
也许这是我自己问题的答案。 Resig 对此发表了一篇文章,这种“修改后的”扩展方法似乎可以满足我的要求。有人可以解释吗?这似乎是一个范围界定问题,但我不明白为什么它的行为就像有人在扩展操作期间实际调用了 getter。
http://ejohn.org/blog/javascript-getters-and-setters/
function extend(a,b) {
for ( var i in b ) {
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
if ( g || s ) {
if ( g )
a.__defineGetter__(i, g);
if ( s )
a.__defineSetter__(i, s);
} else
a[i] = b[i];
}
return a;
}
二次编辑
所以我做了更多的实验,并想出了另外两种似乎可行的方法。一个使用之前发布的 extend 方法,另一个使用 cmets 中指出的 ECMA 规范中的 defineProperties 方法。这个比那个好吗?似乎“mixin”风格更适合我正在寻找的东西,但 Object.create 方式也适用。
var BaseNet = {}
Object.defineProperties(BaseNet, {
"network":{
enumerable:true,
get: function (){return new IPv4Address((this.ipInt & this.netmask.ipInt) >>> 0)}
}
});
function IPv4Address (address){
this.ipInt = address
this.netmask = {}
this.netmask.ipInt = 255
}
IPv4Address.prototype = Object.create(BaseNet)
var ip = new IPv4Address(12345)
ip.netmask
或者,您也可以这样做:
var BaseNet = {}
Object.defineProperties(BaseNet, {
"network":{
enumerable:true,
get: function (){return new IPv4Address((this.ipInt & this.netmask.ipInt) >>> 0)}
}
});
function IPv4Address (address){
this.ipInt = address
this.netmask = {}
this.netmask.ipInt = 255
}
extend(IPv4Address.prototype,BaseNet)
var ip = new IPv4Address(12345)
ip.netmask
【问题讨论】:
-
IPv4Address的原型是一个空对象。ipInt是IPv4Address实例的属性,在调用构造函数时设置。 -
是的,没错,但我没有实例化对象。没有新的,或任何东西。我只是将一个对象 BaseNet 复制到一个未实例化的 function.prototype。
-
哦,抱歉,我以为是反之亦然....您想将
IPv4Address添加到BaseNet....对不起。
标签: javascript node.js