// Don't break the function prototype. // pd - https://github.com/Raynos/pd var proto = Object.create(Function.prototype, pd({ "prop": 42 })); var f = function() { return "is a function"; }; f.__proto__ = proto; console.log(f.hasOwnProperty("prop")); // false console.log(f.prop); // 42 console.log(f()); // "is a function"
.__proto__
является нестандартным и устаревшим.Как я должен наследовать прототипическое создание объекта, но чтобы этот объект был функцией.
Object.create
возвращает объект, а не функцию.
new Constructor
возвращает объект, а не функцию.Мотивация: - кроссбраузерный
finherit
var finherit = function (parent, child) { var f = function() { parent.apply(this, arguments); child.apply(this, arguments); }; f.__proto__ = parent; Object.keys(child).forEach(function _copy(key) { f[key] = child[key]; }); return f; };
Я не верю, что это возможно, поэтому мы должны предложить
Function.create
в список рассылки es-discuss/* Creates a new function whose prototype is proto. The function body is the same as the function fbody. The hash of propertydescriptors props is passed to defineproperties just like Object.create does. */ Function.create = (function() { var functionBody = function _getFunctionBody(f) { return f.toString().replace(/.+\{/, "").replace(/\}$/, ""); }; var letters = "abcdefghijklmnopqrstuvwxyz".split(""); return function _create(proto, fbody, props) { var parameters = letters.slice(0, fbody.length); parameters.push(functionBody(fbody)); var f = Function.apply(this, parameters); f.__proto__ = proto; Object.defineProperties(f, props); return f; }; })();
Как упоминалось в теме es-discuss, существует оператор ES:strawman
prototype, который позволил бы это сделать.
Давайте посмотрим, как это будет выглядеть, используя
var f1 = function () { console.log("do things"); }; f1.method = function() { return 42; }; var f2 = f1 <| function () { super(); console.log("do more things"); } console.log(f1.isPrototypeOf(f2)); // true console.log(f2()); // do things do more things console.log(f2.hasOwnProperty("method")); // false console.log(f2.method()); // 42