克罗克福德原型继承的一个小缺点
Minor drawback with Crockford Prototypical Inheritance
只是在JS中尝试不同的继承技术,并且遇到了关于Crockford的原型继承模式的一些稍微令人不安的东西:
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
var C,
P = {
foo:'bar',
baz: function(){ alert("bang"); }
}
C = object(P);
这一切都很好- 除了当您登录到控制台时-对象显示为f -我看到过可以重新指向构造函数的经典模拟-是否有类似的方法来强制对象(控制台)引用?
问题是它引用了构造函数的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代理还允许设置报告名称的函数,您可以在没有eval的情况下配置,但目前除了在Node.js和Firefox中不可用)。
我要在这里说明一下,所有那些被Crockford和其他许多人所嘲笑的"邪恶"函数都有它们的位置。eval
, with
,扩展本机都启用了特定的技术,否则这些技术是完全不可能的,在适当的场合使用它们并没有错。很可能大多数人都没有资格判断什么时候是正确的。在我看来,在等待解决方案的同时,无害地使用eval
来弥补糟糕的语言语义和工具是完全可以接受的,只要您不将任意代码汇集到eval语句中,就不会对您造成任何伤害。
如果我记录对象,我可以看到: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()}
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- jQuery:循环一个具有不同超时值的循环
- 当包含另一个asp文件时,是否也包含所有引用的样式和脚本页面
- 从javascript创建一个列表
- 节点导出返回一个空对象
- 使用clickToggle并在单击另一个元素时关闭元素
- 我可以在json对象中添加一个函数吗
- 使用javascript将动态表从一个html页面打印到另一个html页
- 将jsp文件下拉列表中的选定项分配给一个java变量(比如String selection)
- 表追加而不附加最后一个元素
- 我如何找到一个句子中的所有空格并替换忽略它们
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 如何在android中使用phonegap将文件从一个文件夹移动/复制到另一个文件夹
- 使用类从一个标记中双击事件
- Javascript,访问一个主要对象模块模式中的每个对象
- 如果使用 lodash 将属性存在于另一个对象中,则向对象添加属性
- JQuery:所有按钮只使用一个监听器有什么缺点吗
- 什么'最合适的数据结构是什么?(使用一个有间隙的数组是否存在缺点或注意事项?)
- 在流星中创建一个传统的网络应用程序有哪些缺点
- 克罗克福德原型继承的一个小缺点