标签:ring bin define com car text get fine tps
上一篇挖了个坑,今天给补上
你是不是也曾像我一样:
编写了个函数明明可以正常工作,但是一做为事件回调函数就报
undefind
了在编写React组件时,看到在构造函数中还得对每个方法bind一下 :
this.funOne = this.funOne.bind(this);
this.funTwo = this.funTow.bind(this);
多么奇怪的写法,为啥子还要再bind下呢? 不如删了,然后就各种
undefined
了
要理解为什么会undefined
还得从this
说起:
var name = ‘tianlang‘;
function getName() {
console.log(this.name);
}
getName();
这段代码会输出:
tianlang
我们只需加一行看是不相关的代码,就能让它报undefined
:
var name = ‘tianlang‘;
function getName() {
‘use strict‘
console.log(this.name);
}
getName();
VM412:4 Uncaught TypeError: Cannot read property ‘name‘ of undefined
at getName (<anonymous>:4:22)
at <anonymous>:6:1
getName @ VM412:4
(anonymous) @ VM412:6
只因在人群中多看了你一眼,就在代码中多写了行use strict
整个程序都崩溃了。
JavaScript执行引擎看到我们写了use strict
就启用了严格模式,严格模式下函数getName中的this指向undefind
,在非严格模式下getName中的this指向全局变量(在浏览器运行环境中就是window, 在node运行环境中就是global)。
就这么简单? 这也不神出鬼没啊。 鬼那能容易看到,如果那么容易看到也就不叫鬼了,接着往下面看:
var name = ‘tianlang‘
var person = {
name: ‘tianlangstudio‘
}
function getName() {
console.log(this.name);
}
person.getName = getName;
person.getName();
getName();
你可以猜下,在看执行结果:
tianlangstudio
tianlang
同样是调用getName
为什么获取的name
不一样呢?
这是因为函数中的this是执行函数调用者的。当我们使用person.getName
的方式执行时getName
中的this就指向了person.
只有在直接执行函数又没有手动绑定操作(后面会介绍)又在非严格模式下this才指向全局变量.
也就是函数内的this具体执行谁跟调用的方式有关。不信你可以再添加两行代码试下:
var personGetName = person.getName;
personGetName();
执行结果是:
tianlang
这就是为什么定义的函数明明可以正常执行,但是一做为事件回调函数就报undefind了。
就像这样:
someHtmlDomNode.addEventListener(‘click‘, person.getName);
你可以认为person.getName
被赋值给了一个变量personGetName
再事件触发时实际是执行的personGetName()
. 不再是person.getName
这种样式的了,它变了。
那怎么让它还是以person.getName
的方式被调用呢?可以再外面包个函数,或者使用手动绑定操作:
someHtmlDomNode.addEventListener(‘click‘, funciton() {
person.getName()
});
someHtmlDomNode.addEventListener(‘click‘, person.getName.bind(person));
这就是为什么定义React组件时为什么还需要对每个方法再bind次了。bind操作就是手动为函数指定this
。除了bind
还有call
和apply
也可以为函数指定执行时的this
值。不同的是bind的返回值是一个新的函数,你可以在你乐意的时候再执行这个函数而call
和apply
是绑定和执行一起执行的,所以它们接受不只一个参数。除了跟bind一样需要一个参数作为this
还需要函数运行所需要的参数,这也是apply
和call
不一样的地方,一个接受数组作为执行函数的参数,一个是使用任意个参数的形式。
fun.apply(thisObj, [‘arg1‘, ‘arg2‘])
fun.call(thisObj, ‘arg1‘, ‘arg2‘, ‘arg3‘)
在React组件中写那么多看是无用的bind真的有点辣眼睛,有没有更好的方式解决呢?
可以实用箭头函数注册事件监听或定义方法,就像这个样子:
someHtmlDomNode.addEventListener(‘click‘, () => {
this.getName()
});
class SomeClass {
constructor(name) {
this.name = name;
}
getName = () => this.name;
}
var obj1 = new SomeClass("tianlang");
obj1.getName();// tianlang
var objGetName = obj1.getName;
objGetName();//tianlang
简单说这是因为:
The best thing is that arrow functions couldn‘t care less about this! Practically, it means they are totally ignoring it (and maybe hoping this will go away), so the context of this right outside the arrow function stays the same inside it
哇! 该煮饭了,拜拜!
标签:ring bin define com car text get fine tps
原文地址:https://blog.51cto.com/14256460/2513634