我是一个陌生的人JavaScript
,来自不同的编程背景,我很难理解如何JavaScript
知道如何解析传递给函数的参数。
让我们看一个简单的例子。从jQuery文档中 .on
,我看到2个不同的签名:
.on(事件[,选择器] [,数据],处理程序)
.on(事件[,选择器] [,数据])
但是,以下代码段可以产生完全有效的代码,并且可以完成预期的工作:
$(function() {
let dat = {a: 1, b: 2}
$('#do').on('click', dat, function(evt) {
alert(evt.data.b);
});
$('#do2').on('click', function(evt) {
alert("click");
});
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="do">
Click!
</button>
<button id="do2">
Click!
</button>
Run Code Online (Sandbox Code Playgroud)
如何JavaScript
“知道” dat
第一种情况下的数据(而不是selector
)?显然,两个签名都没有位置匹配吗?那么,它在内部如何工作?如何在自己的功能中使用此模式?
查看的jQuery源代码on
,手动检查类型,手动忽略所有省略的参数(参数始终从左到右填充):
function on( elem, types, selector, data, fn, one ) {
var origFn, type;
// Types can be a map of types/handlers
if ( typeof types === "object" ) {
// ( types-Object, selector, data )
if ( typeof selector !== "string" ) {
// ( types-Object, data )
data = data || selector;
selector = undefined;
}
for ( type in types ) {
on( elem, type, selector, data, types[ type ], one );
}
return elem;
}
if ( data == null && fn == null ) {
// ( types, fn )
fn = selector;
data = selector = undefined;
} else if ( fn == null ) {
if ( typeof selector === "string" ) {
Run Code Online (Sandbox Code Playgroud)
...等等。
非动态类型背景可能会令人震惊,但这在JS中非常普遍。
\n\n\nJavaScript 如何“知道”第一种情况是数据(而不是选择器)?
\n
事实并非如此。该语言只是将调用者给出的参数传递给函数。弄清楚调用者传递的内容是由函数而不是语言来处理的。
\n\n\n\n\n显然两个签名都没有位置匹配?
\n
JavaScript仅使用位置匹配。从 ES2015+ 开始,它还将为缺少的参数(或传递的参数为 value 的参数undefined
)提供默认值。
\n\n\n那么它在内部是如何工作的以及我如何将这种模式用于我自己的功能呢?
\n
在 JavaScript 中,您不必向函数传递与函数声明的参数数量相同的参数;你可以通过更少或更多。该函数可以通过三种方式告诉您传递的内容:
\n\narguments
每个函数创建的特殊的类似数组的对象,该对象包含参数和一个length
表示有多少个参数的属性。undefined
。这是一个例子:
\n\nfunction example(obj, number, str) {\r\n console.log("Arguments received: " + arguments.length);\r\n if (typeof number === "string") {\r\n // Caller provided a string, not anumber, as the second\r\n // argument; move things around\r\n str = number;\r\n number = undefined;\r\n }\r\n console.log("obj", obj);\r\n console.log("number", number);\r\n console.log("str", str);\r\n}\r\nconsole.log(\'Calling example({}, 42, "forty-two");\');\r\nexample({}, 42, "forty-two");\r\nconsole.log(\'Calling example({}, "no number given");\');\r\nexample({}, "no number given");
Run Code Online (Sandbox Code Playgroud)\r\n.as-console-wrapper {\r\n max-height: 100% !important;\xc2\xa3\r\n}
Run Code Online (Sandbox Code Playgroud)\r\n这是使用剩余参数的示例:
\n\nfunction example(obj, ...rest) {\r\n let number, str;\r\n if (rest.length === 2) {\r\n [number, str] = rest; // This is called "destructuring assignment"\r\n } else {\r\n [str] = rest;\r\n }\r\n if (typeof number === "string") {\r\n // Caller provided a string, not anumber, as the second\r\n // argument; move things around\r\n str = number;\r\n number = undefined;\r\n }\r\n console.log("obj", obj);\r\n console.log("number", number);\r\n console.log("str", str);\r\n}\r\nconsole.log(\'Calling example({}, 42, "forty-two");\');\r\nexample({}, 42, "forty-two");\r\nconsole.log(\'Calling example({}, "no number given");\');\r\nexample({}, "no number given");
Run Code Online (Sandbox Code Playgroud)\r\n.as-console-wrapper {\r\n max-height: 100% !important;\xc2\xa3\r\n}
Run Code Online (Sandbox Code Playgroud)\r\n