首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript函数封装

Javascript函数封装
EN

Stack Overflow用户
提问于 2013-05-30 09:04:35
回答 6查看 250关注 0票数 2

当我定义并调用setTimeout函数时,我得到了undefined undefined,如下所示:

代码语言:javascript
复制
var person = {
    first: 'joe',
    last: 'doe',
    getName: function(){
        console.log(this.first + ' ' + this.last);
    }
}

setTimeout(person.getName(), 2000);

除非我将person.getName()包装在一个函数中,如下所示:

代码语言:javascript
复制
setTimeout(function(){
    person.getName()
}, 2000);

现在我得到了正确的输出。为什么会这样呢?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-05-30 09:21:15

假设你的意思是:

代码语言:javascript
复制
var person = {
    first: 'joe',
    last: 'doe',
    getName: function(){
        console.log(this.first + ' ' + this.last);
    }
}

setTimeout(person.getName, 2000);

你得不到定义的原因是你正在有效地做的是:

代码语言:javascript
复制
var somefunc = person.getName; 
setTimeout(somefunc, 2000);

因此,在window的上下文中调用了一些函数。即window.somefunc()

然而,当你这样做的时候

代码语言:javascript
复制
setTimeout(function(){
    person.getName()
}, 2000);

在调用(而不是传递) person.getName时,会保留getName的上下文

票数 3
EN

Stack Overflow用户

发布于 2013-05-30 15:44:40

我刚刚在这里回答了类似的问题:

How can I pass a parameter to a setTimeout() callback?

setTimeout函数将上下文固定到窗口,因此不可能执行您想要的操作!

为此,我将setTimeout函数包装在另一个可以设置上下文的函数中:

代码语言:javascript
复制
myNass_setTimeOut = function (fn , _time , params , ctxt ){
return setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
            var _deepResultFunction = function _deepResultFunction(){
                //_deepFunction(_deepData);
                _deepFunction.apply(  _deepCtxt , _deepData);
            };
        return _deepResultFunction;
    })(fn , params , ctxt)
, _time) 
};

// lets try this functions :
for(var i=0; i<10; i++){
   setTimeout(function(){console.log(i)} ,1000 ); // stock setTiemout in closure
}

for(var i=0; i<10; i++){
   setTimeout( console.log(i) ,1000 ); // stock setTiemout direct call 
}

for(var i=0; i<10; i++){
   setTimeout(console.log ,1000 , i); // stock setTiemout not compatible IE
}

for(var i=0; i<10; i++){
   myNass_setTimeOut(console.log ,1000 , [i] , console); // wrapped setTimeout
}

所以我来回答你的问题:

代码语言:javascript
复制
var person = {
    first: 'joe',
    last: 'doe',
    getName: function(){
        console.log(this.first + ' ' + this.last);
    }
}

setTimeout(person.getName(), 2000);

启动时:setTimeout(person.getName(), 2000); setTimeout将在未来2秒(2000ms)内执行第一个参数!

但是你的第一个参数的值是什么?:你的函数person.getName( )的结果,所以它等同于:

代码语言:javascript
复制
var _arg1 = person.getName();
setTimeout(_arg1 , 2000);

这是非常不同的:

代码语言:javascript
复制
var _arg1 = person.getName;
setTimeout(_arg1 , 2000);

在第一种情况下,您将函数的结果传递给setTimeout,它等待对函数的引用。在第二种情况下,您传递了对函数的引用(很好,这是预期的),但不是在好的上下文中!

因此,现在您必须修复上下文:核心javascript函数:apply

现在试试这个:

代码语言:javascript
复制
var _arg1 = function(){ person.getName.apply(person) };
setTimeout(_arg1 , 2000);
myNass_setTimeOut(person.getName , 2000 , null , person);

所以你有两个选择:

修复传递给setTimeout.

  • Use函数的每个参数的上下文,该函数将为执行此操作

myNass_setTimeOut函数将会成功!

现在,让我们来看一些更深层次的东西:

代码语言:javascript
复制
var person = {
        first: 'joe',
        last: 'doe',
        getName: function(){
            console.log(this.first + ' ' + this.last);
        } ,
        say : function(sentence){
             console.log(this.first + ' ' + this.last + ' say : ' + sentence)
        }
    }

如何将参数语句传递给setTimeout?

代码语言:javascript
复制
var heSay = "hello !"; setTimeout(person.say(heSay) , 1000 ); heSay = "goodBye !";
// not good : execute immediatly

var heSay = "hello !";setTimeout(function(){person.say(heSay)} , 1000 ); heSay = "goodBye !";
// not good : hesay googbye

var heSay = "hello !"; setTimeout(person.say , 1000 , heSay); heSay = "goodBye !";
// not good bad context

var heSay = "hello !"; setTimeout(function(whatHeSay){person.say(whatHeSay)} , 1000 , heSay);heSay = "goodBye !";
// GOOD ! ok but not compatible with IE

var heSay = "hello !"; myNass_setTimeOut(person.say , 1000 , [heSay] , person ); heSay = "goodBye !";
// just good !

希望这对你有帮助!

编辑:

对于支持bind的现代浏览器来说,不要关心这一点,比如here @dandavis

票数 1
EN

Stack Overflow用户

发布于 2013-05-30 09:08:25

  1. ,你说得太早了。
  2. 保存函数ref时,如果函数ref没有附加到对象,则会损坏该函数。

解决方案?

使用bind,不要提前调用它:

代码语言:javascript
复制
var person = {
    first: 'joe',
    last: 'doe',
    getName: function(){
        console.log(this.first + ' ' + this.last);
    }
}

setTimeout(person.getName.bind(person), 2000);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16826337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档