Javascript 使用构造函数应用/调用
这是对构造函数使用apply和call(提供空对象)的适当方法吗 我只是偷偷地怀疑在幕后:Javascript 使用构造函数应用/调用,javascript,Javascript,这是对构造函数使用apply和call(提供空对象)的适当方法吗 我只是偷偷地怀疑在幕后: function Foo(a,b,c) { this.a = a; this.b = b; this.c = c; } var foo = Foo.call({}, "a", "b", "c"); 不会做和你一样的事 var foo = new Foo("a", "b", "c"); 这: 与以下内容几乎相同: var foo = (function() { var obj = {}; Foo.cal
function Foo(a,b,c) { this.a = a; this.b = b; this.c = c; }
var foo = Foo.call({}, "a", "b", "c");
不会做和你一样的事
var foo = new Foo("a", "b", "c");
这:
与以下内容几乎相同:
var foo = (function() { var obj = {}; Foo.call(obj, "a", "b", "c"); return obj; })();
但不完全是因为一些簿记。你说得对。直接在构造函数中使用call/apply是不同的 您可以修改构造函数,但要测试使用的对象是否是构造函数的实例
function Foo(a,b,c) {
if( !(this instanceof Foo) )
return new Foo(a,b,c)
this.a = a; this.b = b; this.c = c;
}
var findCats = Foo.apply({}, ["a", "b", "c"]);
因此,在构造函数中,如果这个不是Foo的实例
,它调用新Foo(a,b,c)
传递参数
如果要传递的参数数目未知,这当然不起作用
演示:
另一种选择是,构造函数的零参数行为只从Foo
返回新对象,然后作为单独的调用执行.apply()
function Foo(a,b,c) {
if( arguments.length === 0 )
return this;
this.a = a; this.b = b; this.c = c;
}
var findCats = new Foo; // get the empty Foo object
Foo.apply(findCats, ["a", "b", "c"]); // apply the args separately
演示:这不是一回事,本机构造函数通常有很多魔力,因此即使在那里传递null也能奏效
但对于自定义构造函数:
var foo=foo.call({},“a”,“b”,“c”)代码>
Foo
作为正常函数调用,因此Foo
将是未定义的
,因为Foo
作为正常函数调用时不会返回任何内容。即使您在那里添加了返回此
,foo
也不会有指向foo.prototype
的proto链接 var foo=新foo(“a”、“b”、“c”)代码>
可以写成
var foo=new(foo,“a”、“b”、“c”)代码>
这意味着您将按照以下方式实施new
function new(constructor) {
var o = Object.create(constructor.prototype);
var ret = o.constructor.call(o, [].slice.call(arguments, 1));
if (typeof ret !== "number" &&
typeof ret !== "string" &&
typeof ret !== "boolean" &&
ret !== undefined &&
ret !== null
) {
return ret;
}
return o;
}
检查的实例只是代码膨胀。应使用new
@Raynos调用构造函数:您对膨胀有什么看法?没有膨胀,jQuery就不可能!;)。。。我们不需要这种胡说八道,允许您的API使用new
或不使用new。两者都是糟糕的API设计(是的,jQuery有糟糕的API设计)obj=Object.create(Foo.prototype)
这一步真的非常糟糕important@Raynos是的,这就是我所谓的“簿记”注释的意思:-)我理解(可能不准确)问题的焦点是关于这些作业右侧的基本价值,这就是我试图解决的问题。你不是建议函数实际命名为new
,对吗?不,我认为new
实际上会在旧浏览器中作为函数名抛出错误,而不仅仅是在旧浏览器中。这是一个保留字。你可能在想财产名称。保留字在那里是有效的,但较旧的浏览器将中断。啊,您的权利,function new(){}
无效,因为new不允许作为函数名标识符
function Foo(a,b,c) {
if( arguments.length === 0 )
return this;
this.a = a; this.b = b; this.c = c;
}
var findCats = new Foo; // get the empty Foo object
Foo.apply(findCats, ["a", "b", "c"]); // apply the args separately
function new(constructor) {
var o = Object.create(constructor.prototype);
var ret = o.constructor.call(o, [].slice.call(arguments, 1));
if (typeof ret !== "number" &&
typeof ret !== "string" &&
typeof ret !== "boolean" &&
ret !== undefined &&
ret !== null
) {
return ret;
}
return o;
}