Javascript 使用构造函数应用/调用

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

这是对构造函数使用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.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;
}