我在理解这个函数时遇到了一些麻烦:
var toStr = Function.prototype.call.bind( Object.prototype.toString );
toStr([]) // [object Array]
这个函数如何接受第 2 行中的参数?
我在理解这个函数时遇到了一些麻烦:
var toStr = Function.prototype.call.bind( Object.prototype.toString );
toStr([]) // [object Array]
这个函数如何接受第 2 行中的参数?
出色地,
Function.prototype.call
引用“call”函数,该函数用于调用具有选定this
值的函数;.bind
指的是函数原型上的“绑定”函数(请记住:“调用”也是一个函数),它返回一个始终this
设置为传入参数的新函数。this
设置为“toString”函数。因此,结果类似于以下代码:Object.prototype.toString.call( param )
. 然后,“console.log”调用将该函数传递给一个数组,然后就可以了。
编辑请注意,当“param”是一个对象时,这Object.prototype.toString.call( param )
就像param.toString()
真的一样。如果不是,则“调用”函数的语义是以 JavaScript 的正常方式(数字 -> 数字,字符串 -> 字符串等)将其转换为一个。
编辑,2016 年 5 月 24 日— 上面的最后一句话在 ES2015 中不准确。当函数调用作为值涉及时,新的 JavaScript 运行时不会“自动装箱”原始类型。this
我假设你已经知道做什么.call
和.bind
做什么
toStr
现在是一个基本上可以做到的功能:
function toStr( obj ) {
return Function.prototype.call.call( Object.prototype.toString, obj );
}
即它.call
是.call
函数,其上下文参数设置为.toString
函数。通常,该部分已被处理,因为您通常将.call
其用作某些函数的属性,该函数将函数设置为.call
.
这两行代码是一个函数定义,然后是该定义的执行调用,其中传递了一个空数组。复杂性在于解释“这”将指向什么以及为什么。
为了帮助推断这个值,我将下面两个链接中的内容复制到 MDN 的调用和绑定定义。
bind () 函数创建一个新函数(绑定函数),其函数体与调用它的函数(绑定函数的目标函数)相同,并且 this 值绑定到 bind() 的第一个参数。您的代码看起来类似于绑定页面上描述的“快捷方式功能”。
var unboundSlice = Array.prototype.slice; // same as "slice" in the previous example
var slice = Function.prototype.call.bind(unboundSlice);
// ...
切片(参数);
使用call,您可以在调用现有函数时分配不同的 this 对象。this 指的是当前对象,即调用对象。通过 call,你可以编写一次方法,然后在另一个对象中继承它,而不必为新对象重写方法。
当 toStr 被调用时,它传入一个要绑定的数组,其中 this 指针被绑定。使用 bind(),这可以简化。
toStr() is a bound function to the call() function of Function.prototype, with the this value set to the toStr() function of Array.prototype. This means that additional call() calls can be eliminated
.
本质上,它看起来像是 toString 方法的快捷函数覆盖。
bind() - 创建一个新函数,当被调用时,它本身在提供的 this 值的上下文中调用这个函数,在调用新函数时,给定的参数序列在任何提供的参数之前。
阅读此文档以获取有关 JavaScript 中的 bind() 的更多信息
角度示例:
我们定义了函数并将其绑定到对象的父组件:
public callback: object;
constructor() {
this.callback= this.myFunction.bind(this);
}
public myFunction($event: any) {
// Do something with $event ...
}
(父 html)将绑定的对象传递给子组件:
<child-component (callbackFunction)="callback($event)"></child-component>
接收绑定到父函数的对象的子组件:
@Output() callbackFunction: EventEmitter<object> = new EventEmitter<object>();
public childFunction() {
...
this.callbackFunction.emit({ message: 'Hello!' });
...
}
JS到英文翻译——
var toStr = Function.prototype.call.bind(Object.prototype.toString);
bind
创建 的新call
函数Object.prototype.toString
。
现在您可以使用任何将应用于Object.prototype.toString
.
像这样:
toStr([]) // [object Array]
为什么不直接打电话Object.prototype.toString.call([])
??
回答:
当然,你可以。但是 OPs 方法为此目的创建了一个专用的和去方法化的函数。
这真的被称为去方法化。
你可以这样做:
var toStr = Object.prototype.toString.call([]);
问题是:调用立即执行。你想要的是延迟调用的执行。
*由于函数在 Javascript 中也是一个对象,您可以使用任何函数作为“调用”中的第一个参数,而不是将对象作为第一个参数传递。*此外,您可以像在任何对象上一样使用调用点。
Function.prototype.call.bind( Object.prototype.toString ),复制调用函数,并将其“ this ”设置为Object.prototype.toString。您在“toStr”中保存了这个新的调用函数副本。
var toStr = Function.prototype.call.bind( Object.prototype.toString );
现在,您可以随时执行这个新的调用副本,而无需设置 'this',因为它的 'this' 已经绑定到 Object.prototype.toString 。
Object.prototype.toString.call([]) //work well
const toStr = Object.prototype.toString.call
toStr([]) // unfortunately, this does not work
bind
来更正this
指向的位置。const toStr = Object.prototype.toString.call.bind(Object.prototype.toString)
toStr([]) //work well
Object.prototype.toString.call
和Function.prototype.call
const toStr = Function.prototype.call.bind(Object.prototype.toString)
toStr([]) //done
概括
function f(){console.log(this, arguments)}
f.call
和Function.prototype.call.bind(f)
f.call(1,2,3)
和Function.prototype.call.bind(f,1)(2,3)