var singleton = function(fn) { var result; return function() { return result || (result = fn.apply(this, arguments)); } } var createMask = singleton(function() { return document.body.appendChild(document.createElement('div')); }); createMask();
var singleton = function(fn) { var result; return function() { return result || (result = fn()); } } var createMask = singleton(function() { return document.body.appendChild(document.createElement('div')); }); console.log(createMask());
区别在于:fn()和fn.apply(this, arguments);
结果都是一样..
能不能说下具体什么原因?
fn()没有参数时二者无差别;如果需要传不确定个数的输入参数时,就只能选择fn.apply
主要还是涉及到作用域的区别,其他的还真没有其他的区别
作用域的区别
var singleton = function(fn) { var result; return function() { //代码三 return result || (result = fn.apply(this, arguments)); } } var createMask = singleton(function() { //代码二 return document.body.appendChild(document.createElement('div')); }); createMask(); //代码一
这里先忽略fn.apply(this, arguments)以及fn()之间的区别,我们先看下执行createMask这个方法时,发生了什么事情
1)createMask方法 的本质,是singleton方法执行后返回的一个函数(代码三),而singleton方法执行的时候传入参数,就是代码二那里的一个匿名函数,将代码结构稍做调整可得到如下代码
//代码四
var createMask = function(param_0){ var result; var fn = function(){ return document.body.appendChild(document.createElement('div')); }; return result || (result = fn.apply(this, arguments)); } createMask();
2)原始代码示例的createMask调用,是没有传入参数的,即createMask(),假如这个时候createMask方法需要传入一些传输,比如上面代码四的param_0,该怎么做呢?
很自然的,我们想到可以这样调用createMask(param_0)
假如又新增一个param_1参数呢?简单,createMask(param_0, param_1)
假如又新增一个param_2参数呢?。。。没完没了了
有没有一劳永逸的办法,无路那我传多少个参数,都不用再去改上面的代码?
答案是:apply方法
3)apply方法的使用:func.apply(thisObj, arguments)
thisObj:func方法被调用时,方法内部this指针指向的对象
arguments:func方法被调用时,传递给func的参数,通过数组的形式传入
举例:
function hello(a ,b){ alert(this); //this指针默认指向window,具体可参见 javascript权威指南 alert(a+',' +b); } hello.apply(null, [1, 2]); //这段代码执行下就大致明白了
4)具体到最初的例子,如果createMask压根就不会有参数,那fn.apply(this, arguments)的确是不必要的
就是说fn.apply(this, arguments)只是为了方便传递参数而已
@深蓝色梦想: 是的,可以这么认为 :-)