Crockford Prototypical Inheritance的一个小缺点 [英] Minor drawback with Crockford Prototypical Inheritance

查看:68
本文介绍了Crockford Prototypical Inheritance的一个小缺点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JS中尝试不同的继承技术,并且遇到了一些关于Crockford的Prototypal Inheritance模式的轻微令人不安的事情:

Just experimenting with different inheritance techniques in JS, and came across something mildly discomfiting about Crockford's Prototypal Inheritance pattern:

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

var C,
    P = {
         foo:'bar',
         baz: function(){ alert("bang"); }
         }

C = object(P);

当你登录到控制台时,除了之外 - 对象出现了作为F.我见过你可以重新指定构造函数的经典仿真 - 是否有类似的方法来强制对象(控制台)引用?

It's all good - except when you log to console - the object appears as F. I've seen classical emulation in which you can repoint the constructor - is there a similar method to coerce the objects (console) reference?

推荐答案

问题在于它指的是构造函数的 name 。这很快成为关于函数表达式和语句以及name属性的讨论。结果是完全不可能在运行时创建新的命名函数而不使用eval。只能使用函数语句 function fnName(){} 来指定名称,并且除了评估代码之外,不可能动态地构造该代码块。 var fnExpression = function(){} 导致分配给变量的匿名函数。函数的 name 属性是不可变的,所以这是一个完成的交易。使用函数(arg1,arg2,return'fn body';)也只能生成匿名函数,尽管它与eval类似。

The issue is that it's referring to the name of the constructor function. This quickly becomes a discussion about function expressions and statements and the name property. Turns out is is completely impossible to create a new named function at runtime without using eval. Names can only be specified using a function statement function fnName(){} and it's not possible to construct that chunk of code dynamically aside from evaling it. var fnExpression = function(){} results in an anonymous function assigned to a variable. The name property of functions is immutable so it's a done deal. Using Function("arg1", "arg2", "return 'fn body';") also only can produce an anonymous function despite being similar to eval.

这基本上只是JS规范中的一个疏忽(Brendan Eich表示他后悔以10年左右的方式定义显示名称)并且正在讨论针对ES6的解决方案。这将为导出调试工具的函数显示名称引入更多语义,或者可能是一种设置和调整它的明确方法。

It's basically just an oversight in the JS spec (Brendan Eich stated he regrets defining the display name the way he did 10 or so years ago) and a solution is being discussed for ES6. This would introduce more semantics for deriving a function's display name for debug tools or perhaps an explicit way to set and adjust it.

现在你有一条路由:eval,或者一些其他形式的可配置代码的延迟执行。 (按任何其他名称评估......)

For now you have one route: eval, or some other form of late execution of configurable code. (eval by any other name...)

function displayName(name, o){
  var F = eval("1&&function "+name+"(){}");
  F.prototype = o; 
  return new F;
}

单独的函数语句不会从eval返回,而是执行1& &安培; fnStatement 将该东西强制转换为可返回的表达式。

The function statement alone won't return from eval, but doing 1 && fnStatement coerces the thing into an expression which is returnable.

(Harmony Proxies还允许设置报告名称的函数您可以在没有eval的情况下进行配置但除了Node.js和Firefox目前之外不可用。

(Harmony Proxies also allow setting up functions that report names which you can configure without eval but that's not usable except in Node.js and Firefox currently).

我将在这里做一个说明所有那些邪恶的功能克罗克福德和其他许多人都有自己的位置。 eval with ,扩展本机所有启用特定技术,否则完全不可能,并且在使用它们时没有错场合是对的。很可能大多数人没有资格判断何时是正确的。在我看来,使用 eval 无害地弥补糟糕的语言语义和工具,等待解决方案是完全可以接受的,并且只要你是不会造成任何伤害不要将任意代码汇集到该eval语句中。

I'll make a note here that all those "evil" functions that have been shat upon by Crockford and many others ALL have their place. eval, with, extending natives all enable specific techniques which are otherwise completely impossible and it's not wrong to use them when the occasion is right. It's just likely that most people aren't qualified to make the judgement of when that time is right. In my opinion using eval harmlessly to make up for poor language semantics and tools while waiting for a solution is perfectly acceptable and won't cause you any harm as long as you're not funneling arbitrary code into that eval statement.

这篇关于Crockford Prototypical Inheritance的一个小缺点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆