Crockford Prototypical Inheritance的一个小缺点

时间:2011-11-09 23:12:20

标签: javascript prototypal-inheritance

在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.我已经看到了可以重新指定构造函数的经典仿真 - 是否有类似的方法来强制对象(控制台)参考?

2 个答案:

答案 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目前之外不可用。

我将在这里做一个说明,所有那些被克罗克福德和其他许多人所玷污的“邪恶”功能都取而代之。 evalwith,扩展本机都会启用特定的技术,否则这些技术是完全不可能的,并且在适当的时候使用它们并没有错。很可能大多数人没有资格判断何时是正确的。在我看来,在等待解决方案时,无害地使用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()}

相关问题