作用域--高手都容易犯错的地方

在js中,我们都知道,this的指向是由它被调用时的上下文所决定的。例如:

window.id = 888;

var data = {
      id      :  999,
     getId : function(){
           console.log(this.id)
    }
}

data.getId(); //  999;

var getId = data.getId;

getId();  // 888

当我们在data上调用getId方法时,this显然是指向data对象的。这个很好理解,我们需要注意的是,当我们把data上的getId方法赋给一个变量的时候,这个时候的作用域,就悄悄地发生了变化,通常都会指向最外层的作用域上。比如window对象。

通常认为,把某个对象上的方法赋给一个局部变量保存,是一种优化,但是当涉及到方法体内有this的时候,就要小心了。当然,可以使用call,apply,bind等改变作域,但是在这个例子上,这样做是简单问题复杂化了。

或许你会认为这么简单的道理,高手怎么会犯呢?常言道,淹死的都是会游泳的。下面我发一段摘到艾伦项目里的一段bug:

//扫描边界
    //扫描key的左右边界
    //当前页面的左右边
    MasterProto.scanBounds = function(currPage, currkey) {
        var recordParallaxMaster = this.recordParallaxMaster,
            currKey = recordParallaxMaster[currPage],
            filter = {},
            i = currPage,
            prevKey, nextKey;

        //往前
        while (i--) {
            prevKey = recordParallaxMaster[i];
            if (prevKey && prevKey !== currkey) {
                filter[‘prev‘] = prevKey;
                break;
            }
        }

        //往后
        nextKey = recordParallaxMaster[currPage + 1];

        //如果有下一条记录
        if (nextKey && nextKey !== currkey) {
            //如果不是当期页面满足范围要求
            filter[‘next‘] = nextKey;
        }

        //当前页面
        if (currKey) {
            filter[‘curr‘] = currKey;
        }

        return filter;
    }
//page转化成母版ID
    MasterProto.recordParallaxMaster= function(pageIndex) {
        return this.recordParallaxMaster[pageIndex];
    }

怎么样,现在这个样子是不是变以不是那么容易发现了。其实简化一下,就得到了我上面那个例子。

作用域--高手都容易犯错的地方,布布扣,bubuko.com

时间: 2024-09-30 15:33:09

作用域--高手都容易犯错的地方的相关文章

javascript sort方法容易犯错的地方

sort方法用来对数组排序非常方便.但是sort(func)这个func参数的构造却很容易混淆. 这个func的作用是,把排序结果里任意相邻两项a,b放入到func里来执行,如果返回值都为-1,则为正序排列,如返回值都为1,则为逆序排列. 例如,[1,3,65,97,45,6,2] 如果要正序,就应该写成[1,3,65,97,45,6,2].sort(function(a, b){return a - b;}), 如果要逆序:[1,3,65,97,45,6,2].sort(function(a,

[C/C++]_[初级]_[编程容易犯错的地方]

场景: 1. 这里总结一些日常的容易犯错的细节. 问题1:一个类A有成员变量int deleted,给定一个A的对象指针 *a, 判断deleted为真的时候输出一个语句. 一般情况下新手会这样写: if(a) { if(a->deleted) { cout << "deleted" << endl; } } 但这样其实不够精简和浪费行数, 应该这样. if(a && a->deleted) { cout << "

一些经常容易犯错的地方(未完)

最近几场比赛经常会犯一些很简单很诡异的错误,总结一下,以后注意 1. if(a[i]==b)不要写成if(a[i]=b) 2. scanf("%lld",&n)不要写成scanf("%lld",n) 3. 不要太相信int,能开long long,尽量long long 4. sort必须要有using namespace std(真心不知道这是咋打错的)

关于C#编程中引用与值类型赋值的一些容易犯错的地方

值类型与引用类型的区别在于:值类型在赋值的时候是拷贝值,引用类型在赋值的时候的拷贝引用.记住这一个原则,我们再来分析一些具体情况: 1 PointStruct pt1 = new PointStruct(2,2); 2 PointStruct pt2 = pt1; 3 PointStruct[] ptsArray = new PointStruct[3]; 4 ptsArray[0] = pt1; 5 ptsArray[1] = pt2; 6 List<PointStruct> ptsList

css犯错的地方

1. clip属性要求元素的position必须是absolute, 而设置成absolute以后,该元素就从正常的文档流中拿走了..切记. 2. 居中效果:margin: 0 auto 是放在元素身上.并不是加在它的父元素之上..

Makefileeasy犯错的语法

1.引言 近期学习android的Build系统,接触最多的自然就是Makefile语法.发现非常多easy出错的地方,不避开这些错误语法没法真正了解Makefile的内涵.以下就介绍遇到的一些让人困惑的语法错误 2.列举easy犯错的地方 ifeq条件推断 ifeq($(fro),no) endif 多么简单的语法.可是运行会报错例如以下: Makefile:2: *** missing separator. Stop. 原因: ifeq和左括号'('之间是必须有空格的. shell脚本的使用

朱晔和你聊Spring系列S1E6:容易犯错的Spring AOP

标题有点标题党了,这里说的容易犯错不是Spring AOP的错,是指使用的时候容易犯错.本文会以一些例子来展开讨论AOP的使用以及使用过程中容易出错的点. 几句话说清楚AOP 有关必要术语: 切面:Aspect,有的地方也叫做方面.切面=切点+增强,表示我们在什么点切入蛋糕,切入蛋糕后我们以什么方式来增强这个点. 切点:Pointcut,类似于查询表达式,通过在连接点运行查询表达式来寻找匹配切入点,Spring AOP中默认使用AspjectJ查询表达式. 增强:Advice,有的地方也叫做通知

应试教育的死穴,恰在于堵死了孩子“犯错”的空间

今天周日,闲着没事,来公司梳理一下最近的项目心得,又翻起了前段时间看到的文章<应试教育的死穴,恰在于堵死了孩子"犯错"的空间>,来浅谈一下自己的感受吧! 还是从自身谈起,小时候手笨,脑子不是很灵活,于是会出现各种的问题,这时候老师就开始发火.生气,轻则骂几句,重则棍棒伺候.于是在这种环境下,总是害怕犯错事,害怕犯错误. 还有一种情景,就是所谓的考试了,尤其是语文考试,相比大家都经历过,对于一篇阅读理解的分析,每个人都有自己的见解,写写自己的心理体会不就得了,可总是会有一种所

哪些要素在做产品需求的时候容易犯错?

产品经理是一个思考的工种,而多想多思考成为产品经理成长最为关键点.而经验会帮助产品经理在产品需求认知和产品设计上不会犯错误,而快速进入角色.很多新手却办不到这一点. 一.判别需求是否真实存在?需求真伪性 当产品经理接到一个业务部门的需求,一个老板的需求.很多人惯性的思维是如何完成这个需求.而展开对需求思考.但是在此之前,我们需要去判别这个需求的真伪性.如果是伪需求,那么做出来是对我们的产品没有任何的意义.需求是否真实存在,真实性如何?是否有场景可以承接这个需求本身. 二.表面需求后,没有去了解更