gpt4 book ai didi

javascript - 新建时使用可变参数

转载 作者:行者123 更新时间:2023-11-29 10:49:42 24 4
gpt4 key购买 nike

我有一个参数列表,例如 var args = ['blah', 1, 3.9],我想将它应用于需要更新的内容,例如 new bleh。 Thinggy(a, b, c)

我想执行以下操作 var m = {}; bleh.Thinggy.apply(m, args);

我担心有些事情我没有想到,有人知道这是否安全吗?

最佳答案

您当前的方法存在缺陷,因为原型(prototype)继承将无法按预期工作。
构造函数的 method.apply(context, args) 等效于:

// Given a list of arguments `args`:
var bindArgs = [Constructor.prototype].concat(args);
new (Function.prototype.bind.apply(Constructor, bindArgs));

Function.prototype.bind的 Angular 色和 Function.prototype.apply在相应的文档中进行了解释。 记住:.bind 返回一个函数!

为简单起见,我将解释如何使用 .bind 来处理固定数量的参数,比如两个。然后,以下具有相同的效果:

Math.max.apply(Math, 2, 3);
Math.max.bind(Math, 2, 3)();

Math.max.apply(Math, 2, 3, 4, 5);
Math.max.bind(Math, 2, 3)(4, 5);

如果您看过文档,您肯定会理解第一种形式。第二种形式虽然更棘手。 在这种情况下有效,因为参数在 Math.max 中的位置不相关。考虑了所有参数的最大值,所有参数都被同等对待。

现在,下面是一个带有自定义函数的示例:

function echoMe(name, age) {
console.log('Hello ' + name + '. Your age is ' + age);
console.log('this is ', this);
}
echoMe('Rob', '19');
// "Hello Rob. Your age is 19"
// "this is [object DOMWindow]" (non-strict mode)
var echoYou = echoMe.bind(null, "Oops");
echoYou("Peter", "19");
// "Hello Oops. Your age is Peter"
// "this is null"

因为在这种情况下参数的位置很重要,所以最后一个例子显示出一些奇怪的东西。实际上,第一个参数通过 .bind 方法绑定(bind)到“Oops”。传递给绑定(bind)函数 echoYou 的参数被附加到参数列表中。此外,您注意到上下文 this 已更改为 null

有趣.. 让我们尝试使用 .apply 更改上下文:

function printThisFood() {
console.log("this.food is " + this.food);
}
printThisFood.apply({food: "Fish"});
// "this.food is fish"
var locked = printThisFood.bind({food: "Strong"});
locked.apply({food: "Weak"});
// "This.food is Strong"

如您所见,this.food 仍然指向通过 .bind 定义的上下文中的方法!


因此,我们知道如何锁定函数的上下文,以及将任意数量的固定参数传递给函数。这可以应用于构造函数,从而产生我在答案之上呈现的函数。要验证它是否按预期工作:

function Constructor() {
console.log(this instanceof Constructor); // true
console.log(this, arguments); // Convince yourself via console
}
var bindArgs = [Constructor.prototype].concat([1, 2]);
// is equal to [Constructor.prototype, 1, 2]

var BoundConstructor = Function.prototype.bind.apply(Constructor, bindArgs);
var instance = new BoundConstructor();

// Eliminated intermediate variable, and put on one line
var instance = new (Function.prototype.bind.apply(Constructor, bindArgs));

注意:我在单行代码中省略了圆括号 (),因为没有这些也可以初始化构造函数。 new Imagenew Image() 的行为相同。
要立即从构造的方法中读取属性(或调用方法),您可以将整个表达式括在括号中或附加 () 以消除歧义:

(new (Function.prototype.bind.apply(Constructor, bindArgs))).method()
new (Function.prototype.bind.apply(Constructor, bindArgs))().method();

注2:它仍然认为附加参数附加到参数列表。此属性还可用于“预设”给定构造函数的第一个参数:

function Stupid(obvious1, obvious2, foo) { this.interesting = foo; }
Stupid.prototype.onlymethod = function() { return this.interesting};
var saveKeyStroke = Function.prototype.bind.call(Stupid, Stupid.prototype, 1, 2);
// Or, equivalent:
//var saveKeyStroke=Function.prototype.bind.apply(Stupid,[Stupid.prototype,1,2]);

new saveKeyStroke('Fourth argument').onlymethod(); // "Fourth argument"
new saveKeyStroke().onlymethod(); // undefined
(new saveKeyStroke).onlymethod(); // undefined

关于javascript - 新建时使用可变参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12827140/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com