gpt4 book ai didi

Javascript/Typescript .bind() 获取绑定(bind)函数中的变量

转载 作者:行者123 更新时间:2023-12-02 22:43:56 25 4
gpt4 key购买 nike

我想将一个变量绑定(bind)到回调函数,但是 mongoose 已经将一个名为 val 的参数嵌入到该函数中。当我想使用 .bind() 将另一个值绑定(bind)到回调函数时,我丢失了原始 val 属性。有没有办法可以保留原始参数并使用 .bind() 添加我的变量?下面是一个例子。

// gets val parameter from validator
const maxLengthValidator = (val: string): boolean => {
if (val.length > 255) return false;
return true;
};

const userSchema = new Schema({
email: {
type: String,
required: true,
// unique: true
validate: [
{
validator: maxLengthValidator, // includes a val attribute from post request
msg: 'too short'
},
]
},
password: {
type: String,
required: true
}
});

export default model('User', userSchema);

我想做什么:

// gets val parameter from validator
const maxLengthValidator = (val: string, boundary: number): boolean => {
if (val.length > boundary) return false;
return true;
};

...
validate: [
{
validator: maxLengthValidator.bind(this, 255), // doesn't work, would need to specify the string for the val parameter
msg: 'too short'
},
]
...

所以我可以在验证器对象中设置最大长度。

最佳答案

curry

您可以更改函数,因此它不再采用两个参数,而是采用一个参数,然后返回采用第二个参数的第二个函数。这种已知技术被称为 curry .

// maxLengthValidator :: number -> string -> boolean 
const maxLengthValidator = (boundary: number) => (val: string) : boolean => {
if (val.length > boundary) return false;
return true;
};

// ... later ...

validator: maxLengthValidator(255);

这样您就可以通过调用函数来创建不同的验证器:maxLengthValidator(10) 将为您提供一个可以使用的 10 个字符的验证器。因为它是一个函数,所以您也可以将它分配给一个变量:

//userNameLengthValidator :: string -> boolean
const userNameLengthValidator: (val: string) => boolean = maxLengthValidator(10);

交换参数以适应部分分配

不要先取值然后取最大长度,而是先取长度。与柯里化(Currying)函数所做的事情相同,但这个函数仍然可以采用两个参数:

const maxLengthValidator = (boundary: number, val: string): boolean => {
if (val.length > boundary) return false;
return true;
};

// ... later ...

validator: maxLengthValidator.bind(this, 255);

相同的基本思想。不过,这一次您有了更多的灵 active - 您可以使用两个参数 maxLengthValidator(10, username) 调用该函数,或者仅使用一个参数部分应用它。后者产生与柯里化(Currying)几乎相同的东西,因为你仍然得到一个具有相同签名的新函数:

//userNameLengthValidator :: string -> boolean
const userNameLengthValidator: (val: string) => boolean = maxLengthValidator.bind(this, 10);

尽管有相似之处currying is not partial application 。此外,还可以柯里化(Currying)任意数量(任意数量的参数)的函数,以便能够一次获取一个或多个参数。例如,您可以看到 _.curry在洛达什

function add4(a, b, c, d) {
console.log(a + b + c + d);
}

const curryAdd4 = _.curry(add4);

curryAdd4(1)(2)(3)(4);
curryAdd4(1, 2, 3, 4);
curryAdd4(1)(2, 3)(4);
curryAdd4(1, 2, 3)(4);
curryAdd4(1)(2, 3, 4);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

使用占位符或从右侧部分应用

您可以保留签名不变,只更改部分应用程序。 Function#bind 不是很灵活,但您可以编写自己的或(更好)使用库。我将再次使用 Lodash,因为它对这些有一个很好的实现:

带有占位符的部分应用

允许您在部分应用时跳过一些参数。所以你可以跳过第一个,只设置第二个:

const maxLengthValidator = (val, boundary) => {
if (val.length > boundary) return false;
return true;
};

//userNameLengthValidator :: string -> boolean
const usernameLengthValidator = _.partial(maxLengthValidator, _, 10);

console.log(usernameLengthValidator("usernameTooLong"));
console.log(usernameLengthValidator("user"));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

从右侧部分应用

从右到左开始部分应用,因此它将首先设置边界:

const maxLengthValidator = (val, boundary) => {
if (val.length > boundary) return false;
return true;
};

//userNameLengthValidator :: string -> boolean
const usernameLengthValidator = _.partialRight(maxLengthValidator, 10);

console.log(usernameLengthValidator("usernameTooLong"));
console.log(usernameLengthValidator("user"));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

关于Javascript/Typescript .bind() 获取绑定(bind)函数中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58489077/

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