function a () {
return "foo";
}
a.b = function () {
return "bar";
}
function c () { };
c.prototype = a;
var d = new c();
d.b(); // returns "bar"
d(); // throws exception, d is not a function
有什么方法d
可以成为一个函数,但仍然从 继承属性a
?
function a () {
return "foo";
}
a.b = function () {
return "bar";
}
function c () { };
c.prototype = a;
var d = new c();
d.b(); // returns "bar"
d(); // throws exception, d is not a function
有什么方法d
可以成为一个函数,但仍然从 继承属性a
?
实际上,事实证明这是可能的,尽管是以一种非标准的方式。
Mozilla、Webkit、Blink/V8、Rhino 和 ActionScript 提供了一个非标准__proto__
属性,允许在创建对象后更改其原型。在这些平台上,以下代码是可能的:
function a () {
return "foo";
}
a.b = function () {
return "bar";
}
function c () {
return "hatstand";
}
c.__proto__ = a;
c(); // returns "hatstand"
c.b(); // returns "bar"; inherited from a
这可能对任何不需要担心跨平台兼容性的人有用。
但是请注意,只有对象的属性才能被继承。例如:
var d = {};
d.__proto__ = a;
d.b(); // returns "bar"
d(); // throws exception -- the fact that d is inheriting from a function
// doesn't make d itself a function.
简短的回答:不可能。
这行代码:
var d = new c();
自动假定它d
是一个对象。除非c
是内置对象的构造函数,例如,Function
。但是如果c
已经被语言定义了,你就不能操纵它的原型,也不能从你喜欢的任何东西“继承”它。好吧,在某些解释器中你可以,但你不能在所有解释器中安全地做到这一点——标准说:“你不要弄乱标准对象,否则解释器会打击你!”。
内置对象是“唯一的”,JavaScript 不提供复制它们的方法。如果不使用不兼容的技巧,就不可能重新创建字符串、数字、函数等。
基于关于类似问题的元讨论, 我将根据@alexander-mills原件在此处发布此答案
首先创建一个继承的对象 Function
const obj = Object.create(Function.prototype); // Ensures availability of call, apply ext
然后将自定义方法和属性添加到 obj
接下来声明函数
const f = function(){
// Hello, World!
};
并设置obj
为原型f
Object.setPrototypeOf(f,obj);
const obj = Object.create(Function.prototype);
// Define an 'answer' method on 'obj'
obj.answer = function() {
// Call this object
this.call(); // Logs 'Hello, World'
console.log('The ultimate answer is 42');
}
const f = function() {
// Standard example
console.log('Hello, World');
};
Object.setPrototypeOf(f, obj);
// 'f' is now an object with an 'answer' method
f.answer();
// But is still a callable function
f();
是的,如果您使用__proto__
Daniel Cassidy 提到的财产,这是可能的。诀窍是c
实际返回一个已a
附加到其原型链的函数。
function a () {
return "foo";
}
a.b = function () {
return "bar";
}
function c () {
var func = function() {
return "I am a function";
};
func.__proto__ = a;
return func;
}
c.prototype = a;
var d = new c();
d.b(); // returns "bar"
d(); // returns "I am a function"
但是,如果您想instanceof
返回更好的结果,则需要对原型链进行更多调整。
d instanceof c // true
d instanceof a // false
c instanceof a // false
它真的必须是一个原型链吗?您可以使用 mixin 模式使函数具有 a 的所有属性。如果你真的想要,你甚至可以用一个很好的“新”语法包装它来伪造它。
function a () {
return "foo";
}
a.b = function () {
return "bar";
}
function c () {
var f = function(){
return a();
};
//mixin all properties on a
for(var prop in a){
f[prop] = a[prop];
}
return f; //just returns the function instead of "this"
};
var d = new c(); //doesn't need the new keyword, but just for fun it still works
alert(d()); //show "foo"
alert(d.b()); //shows "bar"
您可以在不影响 a 的情况下向 d 添加属性。这与您想要的唯一区别是对 a 的更改不会影响 c 的现有“实例”。