[英]Minor drawback with Crockford Prototypical 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.我已經看到了可以重新指定構造函數的經典仿真 - 是否有類似的方法來強制對象(控制台)引用?
問題是它指的是構造函數的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
會將事物fnStatement
轉換為可返回的表達式。
(Harmony Proxies還允許設置報告名稱的功能,您可以在沒有eval的情況下配置這些名稱,但除了Node.js和Firefox之外,這些功能不可用)。
我將在這里做一個說明,所有那些被Crockford和其他許多人所玷污的“邪惡”功能都有它們的位置。 eval
, with
,extends natives都能啟用特定的技術,否則這些技術是完全不可能的,並且在適當的時候使用它們並沒有錯。 很可能大多數人沒有資格判斷何時是正確的。 在我看來,在等待解決方案的同時使用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()}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.