就 JS 的流畅性而言,这里发生了一些事情有点不协调(没关系,一旦我离开 4.0 的基本语言功能,我的 C# 就已经很陈旧了)。
document.write
首先,我可以建议不惜一切代价避免吗?
这有技术上的原因,如今浏览器都在努力规避它们,但它仍然与alert()
到处放置(包括迭代)一样糟糕。
我们都知道 Windows 系统消息弹出窗口有多烦人。
如果你在 Chrome 中,点击CTRL+Shift+J
它,你会得到一个方便的控制台,你可以console.log()
进入(甚至是对象/数组/函数),它将返回数据集/DOM对象的可遍历节点和其他类型的字符串(如职能)。当今 JS 的最佳特性之一是您的 IDE 位于浏览器中。
从头开始编写和保存 .js 文件在控制台中并不是特别简单,但测试/调试再简单不过了。
现在,进入真正的问题。
看看你在用示例 #1 做什么。的重写.prototype.constructor
应该是完全没有必要的,除非那里有一些边缘情况的浏览器/引擎。
在用作构造函数的任何函数内部(即:用 调用new
),该函数基本上是创建一个新对象{}
,将其分配给this
、 设置this.__proto__ = arguments.callee.prototype
和 设置this.__proto__.constructor = arguments.callee
,其中arguments.callee === function
。
var Working = function () {};
var working = new Working();
console.log(working instanceof Working); // [log:] true
Working
不是字符串:你已经把它变成了一个函数。
实际上,在 JS 中,它也是window
(在浏览器中,也就是)的一个属性。
window.Working === Working; // true
window["Working"] === Working; // true
最后一个确实是解决示例 #2 中的困境的关键。
不过,在查看 #2 之前,请注意:
如果您正在做大量的伪子类化,
var Shape = function () {
this.get_area = function () { };
},
Square = function (w) {
this.w = w;
Shape.call(this);
};
如果您希望instanceof
同时使用 Square 和 Shape,那么您必须开始使用原型和/或构造函数,具体取决于您想要继承什么以及如何继承。
var Shape = function () {};
Shape.prototype.getArea = function () { return this.length * this.width; };
var Square = function (l) { this.length = l; this.width = l; };
Square.prototype = new Shape();
var Circle = function (r) { this.radius = r; };
Circle.prototype = new Shape();
Circle.prototype.getArea = function () { return 2 * Math.PI * this.radius; };
var circle = new Circle(4),
square = new Square(4);
circle instanceof Shape; // true
square instanceof Shape; // true
这仅仅是因为我们将原型对象(被每个实例重用)设置为父类的全新实例。我们甚至可以在所有子类之间共享该单一实例。
var shape = new Shape();
Circle.prototype = shape;
Square.prototype = shape;
...只是不要覆盖.getArea
,因为原型继承就像继承公共静态方法。
形状,当然,有shape.__proto__.constructor === Shape
,差不多square.__proto__.constructor === Square
。做一个instanceof
只是通过链接递归__proto__
,检查函数是否与给定的匹配。
而且,如果您以上面列出的方式构建函数 ( Circle.prototype = new Shape(); Circle.prototype.getArea = function () { /* overriding Shape().getArea() */};
,那么circle instanceof Circle && circle instanceof Shape
将自行处理。
混合继承或伪构造函数(返回不是的对象this
等)需要constructor
修改,以使这些检查工作。
...无论如何...关于#2:
了解以上所有内容,这应该很快就能解决。
您正在为所需的函数名称创建一个字符串,而不是创建一个函数本身,并且没有Obj
定义变量,因此您会收到“参考错误”:相反,请将您的“所需名称”设为对象的属性。
var classes = {},
class_name = "Circle",
constructors = [];
classes[class_name] = function (r) { this.radius = r; };
constructors.push(classes.Circle);
var circle = new constructors[0](8);
circle instanceof classes.Circle;
现在一切都很好地定义了,你不会覆盖任何你不需要覆盖的东西,你仍然可以继承.prototype
和覆盖其值为,并使用该对象属性进行查找)。instanceof
data.name
new Function(data.args, data.constructor)
希望任何/所有这些都有帮助。