JavaScript对象可以有一个原型链,但也可以是一个函数吗?
有没有办法让JavaScript对象可以有一个原型链,但也可以是一个函数吗?,javascript,inheritance,Javascript,Inheritance,有没有办法让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是一
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
是一个对象。除非c
是内置对象的构造函数,例如函数
。但是,如果c
已经由该语言定义,您就不能操纵它的原型,也不能从任何您喜欢的地方“继承”它。好吧,在一些口译员中你可以,但你不能在所有口译员中都安全地做到这一点——标准说:“你不能弄乱标准对象,否则口译员会揍你!”
内置对象是“唯一的”,JavaScript不提供复制它们的方法。如果不使用不兼容的技巧,就不可能重新创建字符串、数字、函数等等。它实际上必须是一个原型链吗?可以使用mixin模式使函数具有函数的所有属性。如果你真的想要,你甚至可以用一个漂亮的“新”语法来伪装它
var d = new c();
可以在不影响a的情况下向d添加属性。这与您想要的唯一区别是,对a的更改不会影响c的现有“实例”。事实上,这是可能的,尽管是以非标准的方式 Mozilla、Webkit、Blink/V8、Rhino和ActionScript提供了一个非标准的
\uuuuuuu proto\uuuuuuu
属性,允许在对象创建后更改其原型。在这些平台上,可以使用以下代码:
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"
这可能对任何不需要担心跨平台兼容性的人都有用
但是,请注意,只能继承对象的属性。例如:
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
是的,如果您使用Daniel Cassidy提到的
\uuuu proto\uuuu
属性,这是可能的。诀窍是让c
实际返回一个已将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.
但是,如果希望instanceof
返回更好的结果,则需要对原型链进行更多调整
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"
这是我一段时间以来一直在努力做的事情。特别感谢以上作者的投入 下面是使用“可调用对象”的链式实现: 此外,通过这种“模式”方法,可以使用
Object.freeze()
在Schema
的原型
或原型
对象上创建一个可重用的接口
。这可能是这样的:fn.\uuuuu proto\uuuu=Object.freeze(新模式()。\uuuuu proto\uuuu)
——这不是一个实际的示例,可能需要更多。也就是说,这是一个不同的讨论。试试看,让我知道
希望这对你有帮助。基于a,我在这里根据原文发布这个答案
现在可以以符合标准的方式完成此操作 首先创建一个继承
函数的对象
var $omnifarious = (function(Schema){
var fn = function f(){
console.log('ran f!!!');
return f;
};
Schema.prototype = {
w: function(w){ console.log('w'); return this; },
x: function(x){ console.log('x'); return this; },
y: function(y){ console.log('y'); return this; }
};
fn.__proto__ = (new Schema()).__proto__;
return fn;
})(function schema(){ console.log('created new schema', this); });
console.log(
$omnifarious()().w().x().y()()()
);
然后将自定义方法和属性添加到obj
接下来声明函数
const obj = Object.create(Function.prototype); // Ensures availability of call, apply ext
并将obj
设置为f
const f = function(){
// Hello, World!
};
演示
const obj=Object.create(Function.prototype);
//在“obj”上定义“应答”方法
obj.answer=函数(){
//称这个对象为
this.call();//记录“你好,世界”
log(“最终答案是42”);
}
常数f=函数(){
//标准示例
log('Hello,World');
};
setPrototypeOf(f,obj);
//“f”现在是具有“answer”方法的对象
f、 答案();
//但仍然是一个可调用函数
f()代码>是的,我求助于使用mixin。在我的例子中,a被修改的可能性很小,修改应该反映在d中,但在实践中这不太可能是一件大事。投票否决。这是可能的!AngularJS有一个名为$http
的模块。用法可以是:$http({})
或$http.post()
。这是可能的,但如何实现?@Cody函数$http(){/*code*/}$http.post=function()!我将纠正投票。很抱歉。顺便说一句,我想我有一个解决办法——如果有兴趣的话,请看我的编辑。这在一个相当标准的方式下成为可能,请看
const f = function(){
// Hello, World!
};
Object.setPrototypeOf(f,obj);