持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情
如何在 JavaScript 中使用绑定函数
该函数在调用函数内部bind
创建一个具有新值的函数副本。this
这是bind
函数的语法:
func.bind(thisObj, arg1, arg2, ..., argN);
在哪里,
- func是一个需要用不同的
this
对象调用的函数 - thisObj是一个对象或一个值,需要用
this
函数内部的关键字替换func
- arg1, arg2...argN – 你可以向调用函数传递 1 个或更多参数,类似于
call
函数。
然后该bind
函数返回一个新函数,该函数包含一个新上下文到this
调用函数内部的变量:
func(arg1, arg2);
现在func
可以稍后使用参数执行此函数。
让我们看一个如何在bind
基于类的 React 组件的帮助下使用函数的经典示例:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 1
};
}
handleCode() {
console.log("HANDLE CODE THIS = ", this.state);
}
render() {
return <button onClick={this.handleCode}>Click Me</button>;
}
}
考虑上面的 App 组件。它构成以下内容:
constructor
是一个被称为类并使用new
关键字实例化的函数。render
是一个执行/渲染 JSX 代码的函数。handleCode
是一个记录组件状态的类方法。
如果我们单击该Click Me
按钮,则会收到一条错误消息:Cannot read properties of undefined (reading 'state')
。
你有没有想过为什么会出现这个问题?🤔🤔
你可能期望我们应该能够访问类的状态,因为handleCode
它是一个类方法。但这里有一个问题:
this
里面的handleCode
和类的不一样this
。- 在类内部,
this
是一个具有非静态类方法作为其属性的常规对象。但是this
里面handleCode
会指不同的上下文。 - 老实说,
this
在这种情况下, 的价值取决于从哪里调用函数。如果你看到,handleCode
则正在调用onClick
事件。 - 但是在这个阶段,我们将在函数内部获取 present
undefined
的上下文。this``handleCode
- 我们试图调用
state
未定义值的属性。因此,这会导致上述错误。
this
我们可以通过在方法内部提供正确的上下文来解决这个问题handleCode
。你可以使用该bind
方法执行此操作。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 1
};
this.handleCode = this.handleCode.bind(this); //bind this function
}
handleCode() {
console.log("HANDLE CODE THIS = ", this.state);
}
render() {
return <button onClick={this.handleCode}>Click Me</button>;
}
}
将bind
创建一个新函数并将其存储在this
具有新属性的对象中handleCode
。Bind
将确保类的this
上下文应用于函数this
内部的当前handleCode
。
如何创建自己的map
函数
现在我们已经拥有了所有必要的东西,让我们从创建own
地图函数开始。让我们首先了解构建own
地图功能所需的东西。
这是map
函数的语法:
arr.map(func)
在哪里,
- arr是调用映射的数组。
- func是需要在数组的每个元素上运行的函数。
函数的基本功能map
很简单:
它是一个遍历数组的每个元素并应用作为参数传递的函数的函数。地图的返回类型同样是一个func
应用于每个元素的数组。
现在我们了解了需求,因此我们可以继续创建自己的map
函数。这是我们的新map
函数的代码:
function newMap(func){
let destArr = [];
const srcArrLen = this.length;
for(let i = 0; i < srcArrLen; i++){
destArr.push(func.call(this, this[i]));
}
return destArr;
}
让我们一点一点的理解上面的函数:
- 此函数接受一个名为 的参数
func
。它只不过是一个需要在数组的每个元素上调用的函数。 - 代码的其他部分很容易解释。我们将重点关注以下行:
destArr.push(func.call(this, this[i]));
- 这一行做了两件事:\
- 将更改推送到
destArr
\ - 在方法
func
的帮助下执行call
。这里的call
方法(如前几节所述)将使用方法中存在的对象func
的新值执行方法。this``func
- 将更改推送到
现在让我们看看我们将如何执行我们的newMap
函数。不建议使用以下向现有原始数据类型添加新方法的方法,但为了本文的目的,我们仍然会这样做。
注意: 不要在你的生产代码中遵循以下方法。这可能会损坏现有代码。
Object.defineProperty(Array.prototype, 'newMap', {
value: newMap
});
defineProperty
我们在Array.prototype
.
一旦完成,我们就可以在数组上执行新的 map 函数了。
const arr = [1,2,3];
const newArr = arr.newMap(item => item + 1);
console.log(newArr);
结论
感谢你的阅读!