在JS中尝试不同的继承技术,并且遇到了一些关于Crockford的Prototypal Inheritance模式的轻微不满:
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
var C,
P = {
foo:'bar',
baz: function(){ alert("bang"); }
}
C = object(P);
一切都很好 - 除了,当你登录到控制台时 - 对象显示为F.我已经看到了可以重新指定构造函数的经典仿真 - 是否有类似的方法来强制对象(控制台)参考?
答案 0 :(得分:13)
问题在于它指的是构造函数的name
。这很快成为关于函数表达式和语句以及name属性的讨论。结果是完全不可能在运行时创建新的命名函数而不使用eval。名称只能使用函数语句function fnName(){}
来指定,并且除了评估它之外,不可能动态地构造该代码块。 var fnExpression = function(){}
会导致为变量分配匿名函数。函数的name
属性是不可变的,所以这是一个完成的交易。使用Function("arg1", "arg2", "return 'fn body';")
也只能生成匿名函数,尽管它与eval类似。
这基本上只是对JS规范的疏忽(Brendan Eich表示他后悔以10年左右的方式定义显示名称)并且正在讨论针对ES6的解决方案。这将引入更多语义来导出调试工具的函数显示名称,或者可能是一种设置和调整它的明确方法。
现在你有一个路由:eval,或者其他形式的可配置代码的延迟执行。 (按任何其他名称评估......)
function displayName(name, o){
var F = eval("1&&function "+name+"(){}");
F.prototype = o;
return new F;
}
单独的函数语句不会从eval返回,而是执行1&& fnStatement
将该事物强制转换为可返回的表达式。
(Harmony Proxies还允许设置报告名称的函数,这些函数可以在没有eval的情况下配置,但除了Node.js和Firefox目前之外不可用。
我将在这里做一个说明,所有那些被克罗克福德和其他许多人所玷污的“邪恶”功能都取而代之。 eval
,with
,扩展本机都会启用特定的技术,否则这些技术是完全不可能的,并且在适当的时候使用它们并没有错。很可能大多数人没有资格判断何时是正确的。在我看来,在等待解决方案时,无害地使用eval
来弥补糟糕的语言语义和工具是完全可以接受的,只要你没有将任意代码汇集到该eval语句中,就不会对你造成任何伤害。
答案 1 :(得分:0)
如果我记录对象,我可以看到:Object { foo="bar", baz=function()}
,所以我不明白你的问题......
无论如何,可以使用Object.create()代替Crockford的函数:
var P = {
foo:'bar',
baz: function(){ alert("bang"); }
}
var C = Object.create (P);
console.log(C):
Object { foo="bar", baz=function()}