簡體   English   中英

Crockford Prototypical Inheritance的一個小缺點

[英]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和其他許多人所玷污的“邪惡”功能都有它們的位置。 evalwith ,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM