- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目标:在React组件内的.this()
绑定(bind)过程中,我想完全了解正在制作的引用以及计算机执行的精确步骤。
说明:我有一些代码(在下面列出的定向),在代码内,计算机通过handleChange
行绑定(bind)了this.handleChange = this.handleChange.bind(this);
输入处理程序。有一个父组件MyApp
,它有一个子组件GetInput
和另一个子组件RenderInput
。
问题:
问题1.我的困惑主要来自于认为.this()
自动引用最接近的“父”对象,并且通过.this()
进行绑定(bind)将因此将其重定向到.bind()
写入位置的最接近的父对象。在以下情况下,它似乎重定向到MyApp
组件。但是,MyApp
类是一个函数console.log(typeof MyApp) //expected: function
。因此,为什么.this()
在下面的代码中未引用全局对象?
问题2.调用handleChange处理程序时,计算机将执行哪些逐步过程?是否是以下内容:
RenderInput
组件内的初始调用:<p>{this.props.input}</p>
RenderInput
父元素,它是GetInput
组件:<input value={this.props.input} onChange={this.props.handleChange}/></div>
onChange={this.props.handleChange}
GetInput
组件的父级(即MyApp
组件),并显示:handleChange={this.handleChange}
(这是我最不确定的步骤).this()
绑定(bind)到的位置:this.handleChange = this.handleChange.bind(this);
MyApp
作为this
的绑定(bind)值handleChange
处理程序:handleChange(event) {this.setState({inputValue: event.target.value });}
class MyApp extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ""
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
inputValue: event.target.value
});
}
render() {
return (
<div>
{
<GetInput
input={this.state.inputValue}
handleChange={this.handleChange}
/>
}
{
<RenderInput input={this.state.inputValue} />
}
</div>
);
}
}
class GetInput extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>Get Input:</h3>
<input
value={this.props.input}
onChange={this.props.handleChange}/>
</div>
);
}
};
class RenderInput extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>Input Render:</h3>
<p>{this.props.input}</p>
</div>
);
}
};
最佳答案
让我们从this
和.bind
的行为都不是React特定的事实开始。因此,为简单起见,让我们暂时忘记React,只看一些原始的JS代码(不用担心!稍后我们将返回React)。
现在让我们从头开始,这是一个对象:
{
username: "KamiFightingSpirit"
}
{
username: "KamiFightingSpirit",
logUsername: function () {
console.log( this.username );
}
}
this
到底是什么?
this
指向执行上下文,您可能还听说过:
this
/execution context is anything before the dot that precedes function call.
this
与作用域不同,让我们快速检查一下。它是在执行期间计算的。
const soUser = {
username: "KamiFightingSpirit",
logUsername: function () {
console.log(this.username);
}
};
soUser.logUsername();
// -> KamiFightingSpirit
this
等于
soUser
。
// Let's just borrow the method from soUser
const userNameLogger = soUser.logUsername;
const nestedObjects = {
username: "This property will not be logged", // neither "KamiFightingSpirit" will be logged
sampleUser: {
username: "Igor Bykov",
logUsername: userNameLogger
}
};
nestedObjects.sampleUser.logUsername();
// -> Igor Bykov
this
等于函数调用之前的点之前的对象。在这种情况下,对象是
nestedObjects.sampleUser
的值。
username
:
const nestedObjects = {
username: "undefined will be logged",
sampleUser: {
logUsername: userNameLogger
}
};
nestedObjects.sampleUser.logUsername();
// -> undefined
// this is called constructor function
function User(name) {
// const this = {}; <- implicitly when used with "new" keyword
this.name = name;
// return this; <- implicitly when used with "new" keyword
}
console.log( new User("LonelyKnight") );
// -> {name: "LonelyKnight"}
new
强制创建新对象(并因此创建执行内容)。
new
的情况下调用相同的函数,它将执行但不会创建新对象,并且
this
将被评估为
window
对象。这样,我们将有效地将
name
分配给
window
。
class
。类与构造函数完全一样(实际上,它们是更聪明,更漂亮的构造函数)。
class User {
constructor(name) {
this.name = name;
}
}
class User {
constructor(name) {
this.name = name;
}
changeName(newName) {
this.name = newName;
}
}
let batman = new User("Bat");
console.log(batman.name); // -> Bat
batman.changeName("Batman!");
console.log(batman.name); // -> Batman!
.bind
。在这种情况下没有必要,因为我们在类的实例上执行所有操作。
function Child(f) {
// Random property
this.rand = "A";
f(); // -> Window
}
function User(name) {
this.name = name;
this.logThis = function(){
console.log(this);
}
this.render = function(){
return new Child(this.logThis);
}
}
// Somewhere in React internals (in overly-simplified constructor-based universe)
const U = new User(``);
U.render();
f()
,所以前面没有点,因此没有上下文可在其中执行
f()
。在这种情况下(除非设置了严格模式),
this
会被评估为全局对象,该对象在浏览器中就是
Window
。
// Child component
class Child {
constructor(f) {
setTimeout(
() => f("Superman"), // -> throws "Cannot set "name" of undefined"
100
);
}
}
// Parent component
class User {
constructor(name) {
this.name = name;
}
changeName(newName) {
this.name = newName;
}
render() {
return new Child(this.changeName);
}
}
// Somewhere in React internals (in overly-simplified universe)
const batman = new User("batman");
batman.render();
f()
之前看不到任何内容)将
this
评估为undefined,尝试将新属性分配给undefined,并引发错误,失败了。
.bind
或类似的函数,以确保始终在正确的上下文中执行它。
.bind
到底做什么?
Some internal black magic。为了完全理解它,您可能需要深入研究JS编译器代码(通常以C / C++编写)。
.bind
。如果仔细观察,您会注意到两个polyfill都只包装了对
.apply
或
.call
的调用。因此,有趣的部分实际上并未“公开”。
.bind
功能,我们会发现
.bind
并不那么复杂(至少在基本级别上),它的主要功能只是确保执行上下文始终保持不变。
.customBind
的致命实现:
Function.prototype.customBind = function(obj, ...bindedArgs) {
// Symbol ensures our key is unique and doesn't re-write anything
const fnKey = Symbol();
// Inserts function directly into the object
obj[fnKey] = this;
// Return a wrapper that just calls the function
// from within specified object each time it's called.
return (...args) => obj[fnKey](...bindedArgs, ...args);
};
Object.defineProperty
更好地隐藏它,但它仍然存在。
// Please, never use this code for anything practical
// unless you REALLY understand what you are doing.
// Implements customBind
Function.prototype.customBind = function(context, ...bindedArgs) {
// context => intended execution context
// bindedArgs => original .bind also accept those
// Saves function that should be binded into a variable
const fn = this;
// Returns a new function. Original .bind also does.
return (...args) => {
// Symbol is used to ensure that
// fn's key will not unintentionally
// re-writte something in the original
// object.
const fnSymbol = Symbol();
// Since we can't directly manipulate
// execution context (not doable in JS),
// neither we can just call "context.fn()" since
// .fn is not in context's prototype chain,
// the best thing we can do is to dinamically
// mock execution context, so, we'll be able to
// run our binded function, inside the mocked
// context.
const contextClone = {
...context,
// adds binded function into a
// clone of its intended execution
// context.
[fnSymbol]: fn,
};
// Executes binded function inside the exact clone
// of its intended execution context & saves returned
// value. We will return it to the callee
// later on.
const output = contextClone[fnSymbol](...bindedArgs, ...args);
// Deletes property, so, it'll not leak into
// the original object on update that we're
// going to perform.
delete contextClone[fnSymbol];
// The function that we've run on our clone, might
// possibly change something inside the object it
// operated upon. However, since the object it
// operated upon is just a mock that we've created,
// the original object will stay unchanged. In order
// to avoid such a situation, let's merge our possibly
// changed clone into the original object.
context = Object.assign(context, contextClone);
// Finally, let's return to the callee,
// the result returned by binded function.
return output;
};
};
// Let's test it works!
const soUser = {
name: `Kami`,
logName: function() {
console.log(`My name is ${this.name}`);
},
changeName: function(newName) {
this.name = newName;
},
};
// Let's just borrow these methods from soUser
const soUserOwnedLogger = soUser.logName.customBind(soUser);
const soUserNameChanger = soUser.changeName.customBind(
soUser,
"KamiFightingSpirit"
);
// Let's use borrowed methods into another object.
const outterSystemUser = {
name: `UU-B235`,
soUserLogger: soUserOwnedLogger,
soUserChange: soUserNameChanger,
};
soUserOwnedLogger();
outterSystemUser.soUserChange();
soUserOwnedLogger();
console.log(`"name" in soUuser: ${soUser.name}`);
console.log(`"name" in outterSystemUser: ${outterSystemUser.name}`);
关于javascript - 在React组件中有关.this绑定(bind)的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59310338/
我不知道该怎么做... function f1() { var x = 10; function f2(fx) { var x; x = 6;
早期绑定(bind)和后期绑定(bind)有什么区别? 最佳答案 简短的回答是,早期(或静态)绑定(bind)是指编译时绑定(bind),后期(或动态)绑定(bind)是指运行时绑定(bind)(例如
如何在 SwiftUI View 上使用 Binding(get: { }, set: { }) 自定义绑定(bind)与 @Binding 属性。我已成功使用此自定义绑定(bind)与 @State
我经常发现自己遇到问题,即控件的两个(相关)值被更新,并且两者都会触发昂贵的操作,或者控件可能会暂时处于不一致的状态。 例如,考虑一个数据绑定(bind),其中两个值 (x,y) 相互减去,最终结果用
我想通过我的 ViewModel 控制我的一个窗口的高度和宽度。 这看起来很简单。 但没有。它不起作用。 它检查 ViewModel 的 Width但不是 Height . 奇怪的是,如果我切换 W
UI5中一次性绑定(bind)和单向绑定(bind)有什么区别? 是否有任何用户特定的用例我会使用它们? 我无法从文档中获得太多信息。 最佳答案 单程 它的作用:单向数据流。模型数据的变化(例如通过
(define make (lambda (x) (lambda (y) (cons x (list y))))) (let ((x 7) (p (make 4))) (cons
尽管我或多或少地了解什么是语言绑定(bind),但我很难理解它们是如何工作的。 例如,谁能解释一下如何为 WinAPI 制作 Java 绑定(bind)? 最佳答案 如果您搜索 Foreign Fun
谁能解释为什么我可以重新绑定(bind)列表但不能+? (binding [list vector] (list 1 3)) (binding [list +] (list 1 3)) (bi
我真的很喜欢 Caliburn 和命名约定绑定(bind),我很惊讶 可见性与“CanNAME”约定用于保护 Action 的方式不同。 据我所知, BooleanToVisibilityConver
我了解动态绑定(bind)的实现方式以及静态绑定(bind)和动态绑定(bind)之间的区别,但我只是无法理解动态绑定(bind)的定义。基本上它是一种运行时绑定(bind)类型。 最佳答案 基本上,
http://jsfiddle.net/3NRsd/ var foo = $("div").bind("click", function() { $("div").animate({"hei
这个问题我快疯了...我有一个用户控件,它有一个用于插入操作的 FormView 和一个用于所有其他操作的 GridView。 在这两个控件中,我都有一个 DropDownList,如下所示: '
我有一个绑定(bind)到 ListBox 的地址的 ObservableCollection。然后在 ItemTemplate 中,我使用 {Binding .} 绑定(bind)到当前地址记录。这
如果我有以下简单的 js/knockout 代码: .js( View 模型): var image = ko.observable('http://placehold.it/300x150'); 看
我正在 aurelia 上开发一个自定义属性,让用户在输入文本区域时从列表中进行选择。例如,用法将是这样的: 正如您可能注意到的,auto-complete是属性。现在,当我想显示提示时,我想在自定
我正在使用 EventEmitter2作为我的应用程序内部的消息总线。现在我需要绑定(bind)和取消绑定(bind)一些事件处理程序。因为我也希望他们bind将它们添加到给定的上下文中,我最终得到以
我有以下函数调用: $(".selector").on("click", callback.bind(this, param1, param2)); 在我的回调函数中,我想使用绑定(bind)的 th
我目前正在试验新的编译绑定(bind),并且(再次)达到了我在拼图中遗漏了一个小问题:为什么我必须调用 Bindings.Update?直到现在,我还认为实现 INotifyPropertyChang
我正在阅读一本关于编写 JavaScript 框架的书,并找到了这段代码。但是我不明白它是如何工作的,尤其是 bind.bind 的用法?有人知道吗? var bind = Function.prot
我是一名优秀的程序员,十分优秀!