我正在阅读“JavaScripts The Good Parts”(由Douglas Crockford撰写)。很好。 我无法理解下面的代码。它工作正常。但我无法理解它是如何运作的。 关于此代码有5个问题。
显示该代码后,我会解释更多。
var myTest = {};
Function.prototype.method = function(name, func) {
if(!this.prototype[name])
{
this.prototype[name]=func;
}
};
Function.method('bind', function(that) {
var method = this,
slice = Array.prototype.slice,
args = slice.apply(arguments, [1]); //[A] value of arguments and args
//-------------------------------
//[C] following document.writeln do not work. why?
document.writeln("<C>arguments[0]:", arguments[0]);
document.writeln("<C>arguments[1]:", arguments[1]);
document.writeln("<C>args:",args);
myTest.str1 = 1;
myTest.str2 = "ABC";
document.writeln("<C>str1:", myTest.str1);
document.writeln("<C>str2:", myTest.str2);
//-------------------------------
return function(){
//-------------------------------
//[D] following document.writeln do not work. why?
document.writeln("<D>arguments[0]:", arguments[0]);
document.writeln("<D>arguments[1]:", arguments[1]);
document.writeln("<D>args:",args);
myTest.str3 = 2;
myTest.str4 = "DEF";
document.writeln("<D>str3:", myTest.str3);
document.writeln("<D>str4:", myTest.str4);
//-------------------------------
return method.apply(that, args.concat(slice.apply(arguments, [0]))); //[B] value of arguments and args
};
});
var x= function(){
return this.value;
}.bind({value:666});
//-------------------------------
document.writeln("str1:", myTest.str1, "<br/>"); //[E]show undefined. why?
document.writeln("str2:", myTest.str2, "<br/>"); //[E]show undefined. why?
document.writeln("str3:", myTest.str3, "<br/>"); //[E]show undefined. why?
document.writeln("str4:", myTest.str4, "<br/>"); //[E]show undefined. why?
//-------------------------------
alert(x()); //666 -> no problem
[C],[D],[E]中的document.writeln用于测试。但他们没有像我预期的那样工作。
警报'666'运行良好。 (没问题)
请帮帮我......
-----------在Function.prototype.method中删除if-confition之后我得到了以下结果
[C]arguments[0]:[object Object]
[C]arguments[1]:undefined
[C]args:
[C]str1:1
[C]str2:ABC
str0C:[object Object]
str1C:undefined
str0D:undefined
str1D:undefined
str1:1
str2:ABC
str3:undefined
str4:undefined
[D]arguments[0]:undefined
[D]arguments[1]:undefined
[D]args:
[D]str1:2
[D]str2:DEF
str0C:[object Object]
str1C:undefined
str0D:undefined
str1D:undefined
str1:1
str2:ABC
str3:2
str4:DEF
现在,我想知道[C],[D]中的参数的真正价值,数组的内容......
使用JSON.stringify(arguments [0])),我终于得到了参数的真正价值。
[C]arguments[0]:{"value":666}
这就是我真正想要的。 [C]参数[1],[D]参数[0],[D]参数[1]没有值。所以它们是“未定义的”,对吧。
现在,我想知道“args = slice.apply(arguments,[1]);”在[A]中做。
args = slice.apply(arguments, [1]);
据我所知,slice返回数组的副本。因为我们使用apply,slice使用参数作为这个,[1]作为参数数组。此时,参数只有一个项{“value”:666“}。slice(start,end)返回数组的副本,该数组从'start'开始,以'end'结尾。然后,在这种情况下slice.apply(参数,[1])必须返回从1开始的参数副本。但是正如我们所知,参数只有1个项,所以参数[1]不存在。(arguments [0],{value:666}存在。)然后这是怎么回事?args是未定义的。这是做什么的?有什么我忽略的吗?
在[B]中它返回“method.apply(即,args.concat(slice.apply(arguments,[0])));”。
return method.apply(that, args.concat(slice.apply(arguments, [0])));
在此,[0]是参数数组。 0 ..为什么为零?并且参数未定义。嗯...那么这会返回参数[0]?这是{值:666}?警惕'666'?
我明白了..
中的参数是绑定函数的参数
[B]中的参数是x函数的参数
右?
现在有一个(也许是最后一个)问题.. ^^ 当我调用document.writeln.bind(document,“TEST”)时,Function.method中的'that'是什么('bind',function(that)?
'那'是文件?或'那'是[文件,“测试”]
答案 0 :(得分:0)
Function.prototype.method = function(name, func) { if(!this.prototype[name])
...是你的问题。您不会覆盖现有函数 - 并且Function.prototype.bind
已经存在(并且与您定义的结果具有相同的结果,但没有记录)。这样,您就不会使用自定义实施覆盖它,并且不会执行任何document.writeln
来电或myTest
分配。
您可以删除if条件以进行测试,它会起作用。一旦你在输出中看到会发生什么,你应该能够自己回答其他问题。
现在,我想知道[C],[D]中的参数的真正价值,数组的内容......
只有一个问题:{value:666}
:-)您可以使用JSON.stringify输出:
document.writeln("<C>arguments[0]:", JSON.stringify(arguments[0]));
…
[slicing]然后,在这种情况下,slice.apply(arguments,[1])必须返回从1开始的参数副本。
是。顺便说一句,写slice.call(arguments, 1)
会更容易 - 它们是一样的。
但是我们知道参数只有1项,所以参数[1]不存在。(arguments [0],{value:666}存在。)那么这是如何工作的? args未定义。
不是undefined
,而是空数组[]
。
这是做什么的?有什么我忽略的吗?
bind
需要进一步的可选参数。你没有通过。
在[B]中它返回“method.apply(即,args.concat(slice.apply(arguments,[0])));”。在这里,[0]是参数数组。 0 ..为什么为零?
因为你想得到绑定函数的所有(可选)参数 - 从头开始切片。
参数未定义。嗯...那么这会返回参数[0]?这是{值:666}?警惕'666'?
arguments
未定义,但长度为0,因此整个args.concat(…)
计算为空数组。 that
仍然指向{value: 666}
,是的 - 这是this
关键字的传递内容。
那么所有这些可选参数是什么?
在x
示例中,您只使用了this
,您的函数实际上没有任何参数。但它可能有 - 让我们尝试一个有更多参数的,比如console.log
:
var logger = console.log.bind(console, "Here:");
logger(); // Here:
logger(5); // Here: 5
logger({value:666}); // Here: {value: 666}
如果您对控制台感觉不舒服,可以同样使用document.writeln.bind(document, …
。