推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
whatisnew

请教有一个 javascript 问题

  •  
  •   whatisnew · Apr 16, 2015 · 4606 views
    This topic created in 4072 days ago, the information mentioned may be changed or developed.

    如代码代示,js对象内访问,用 thisobj 都可以,但是在 对象方法内在 callback 里用 this 就会报未定义,但是用 obj.remove 就可以,求大神给指点一下,如何写比较好比较正确。

    define(function() {
    
        var obj = {
    
            add: function(id) {
                // 这里可以用 this
                this.edit(id, function() {
                    // 这里报 this 未定义
                    this.remove(id);
                    // 如果用 obj.remove() 就可以
                    obj.remove(id);
                });
                // 也可以用 obj.edit()
                // 哪种效率比较高呢?
                // 或者是比较标准的正确写法呢?
            },
    
            edit: function(id) {
                console.log('edit');
            },
    
            remove: function(id) {
                console.log('remove');
            }
    
        };
    
        return obj;
    });
    
    31 replies    2015-04-16 11:02:23 +08:00
    Hyperion
        1
    Hyperion  
       Apr 16, 2015   ❤️ 2
    调用this.edit 之前 _this = this;

    在传入函数里使用_this.
    ChiangDi
        2
    ChiangDi  
       Apr 16, 2015 via Android   ❤️ 1
    是报 this.remove 未定义吧?
    sneezry
        3
    sneezry  
       Apr 16, 2015   ❤️ 2
    this.edit(id, function() {
    this.remove(id);
    }.bind(this));

    但是,this.edit不是只接受一个参数吗??
    whatisnew
        4
    whatisnew  
    OP
       Apr 16, 2015
    @sneezry 哈哈,是的,这是一个示例。
    whatisnew
        5
    whatisnew  
    OP
       Apr 16, 2015
    @Hyperion 这样的话在对象内使用 `this` 和 `obj` 有啥区别呢?效率区别?标准区别?
    whatisnew
        6
    whatisnew  
    OP
       Apr 16, 2015
    @ChiangDi 是的,确切的来说是 this.remove 未定义。超出了作用域。
    FrankFang128
        7
    FrankFang128  
       Apr 16, 2015 via Android   ❤️ 1
    极端得讲一下:
    1 this 永远指向 window
    2 除非你显式指定 this
    3 显式地指定this有如下方法:
    3.1 使用点语法指定,如obj.remove
    3.2 使用call和apply指定
    3.3 浏览器内置方法默认指定,如事件的回调等
    3.4 其他不建议的方法
    FrankFang128
        8
    FrankFang128  
       Apr 16, 2015 via Android
    不要再用OOP的角度来理解JS的this了,不然你永远学不会。
    好好看看犀牛书,不要看了蝴蝶书就以为自己会JS了。
    FrankFang128
        9
    FrankFang128  
       Apr 16, 2015 via Android
    3.2 还应加上 bind 等方法。
    whatisnew
        10
    whatisnew  
    OP
       Apr 16, 2015
    @FrankFang128 果然大神,一看就知道我纠结在哪了,真的这么多年 cpp java php 习惯性 oop 了,着手码几行 js 真心不适应,正在强迫自己适应中。

    从前端同事那里借了这个犀牛书,正在专研中!哈哈

    不过,我在 `var obj {..}` 里 `console` 出来了 `this`,出来一个对象,是 `var obj` 声明的这个对象本身。
    如果是 this 指向 window 的话,他应该有更多对象才对吧?
    FrankFang128
        11
    FrankFang128  
       Apr 16, 2015 via Android
    @whatisnew 我上面说的是浏览器,所以用了极端两字。非浏览器的 this 会默认指向 null 或 global
    FrankFang128
        12
    FrankFang128  
       Apr 16, 2015 via Android
    @whatisnew 你说的后半段我没看懂,贴出代码吧
    mcfog
        13
    mcfog  
       Apr 16, 2015 via Android   ❤️ 1
    @FrankFang128 挑个刺,漏了strict mode哈
    FrankFang128
        14
    FrankFang128  
       Apr 16, 2015 via Android
    @mcfog 嗯,“极端”。手机码字
    FrankFang128
        15
    FrankFang128  
       Apr 16, 2015 via Android
    @mcfog 所以就简化了一些
    Septembers
        16
    Septembers  
       Apr 16, 2015 via Android
    @mcfog ES5特性 ES3并没有
    FrankFang128
        17
    FrankFang128  
       Apr 16, 2015   ❤️ 5
    现在有电脑了,就再说下吧。
    this和obj的区别,obj 很简单,就是一个对象的引用,你给 obj 赋值后它就固定了。
    但 this 不是,this 是一个函数在被调用时的上下文:
    1. 只有函数被调用时 this 才能确定是什么。
    如 obj.add 里的第一个 this,被你显式地指定为 obj,所以 this === obj
    但是如果你这样调用 `var anotherAdd = obj.add; anotherAdd()`,那么 anotherAdd 被调用时的 this 就又是 window 了
    2. 每执行一个函数,都对应一个 this。
    所以你 obj.add 里的第2个 this,也就是`this.remove(id);` 这一句里的 this,由于没有显式指定,就有指向 window 了(在这一句话被执行的时候)
    FrankFang128
        18
    FrankFang128  
       Apr 16, 2015
    不知道有没有说清楚,总之就是每看到一个 function 关键字,this 就有可能变化。
    this 跟对象无关,只与 function 有关。
    FrankFang128
        19
    FrankFang128  
       Apr 16, 2015
    17 楼说得有点乱,没看懂就忽略,看 18 楼吧。
    whatisnew
        20
    whatisnew  
    OP
       Apr 16, 2015
    @FrankFang128 懂了!哈哈,太赞了!新技能 get 高兴中
    200cc
        21
    200cc  
       Apr 16, 2015
    js可以用prototype来实现oop.
    感觉这样理解起来更容易.
    Hyperion
        22
    Hyperion  
       Apr 16, 2015   ❤️ 1
    使用this 其实完全没有什么问题, 而且上面对this 的解释似乎有点小问题?

    可以参考MDN 的这个链接, 似乎是有意漏掉了某个?
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

    Javascript 的this 不是难理解, 只是因为它本身的一组特性综合导致他和别的语言不一样. 关于在闭包里使用this , 我最早是从阮一峰的blog 上看到最完整的概述的.

    效率问题, 都是引用. 作为一种习惯, 理解this 很重要, 因为这个已经是通行的做法了.

    掏出犀牛书第六版(第五版没有在学校), p188页 译者注释.

    仅作讨论, 求同存异. 希望不要引起争执.

    书, 个人不提供建议, 自认水平有限. 犀牛这本圣经扫了几遍, 但看红皮还是有很多要补的地方, 比如逻辑操作符具体的特性, 各种实现类方式的利弊, 以及各种兼容实现问题.
    whatisnew
        23
    whatisnew  
    OP
       Apr 16, 2015
    @200cc prototype 实现的 oop 会有效率上的提升吗?因为我看到 prototype oop 在调用的时候太惨了 new(_) 那个下划线,那些个 find 真心觉得是乱码一样,比较难理解。
    Hyperion
        24
    Hyperion  
       Apr 16, 2015
    @whatisnew 可以去看Javascript 高级程序设计, 相关例子会比犀牛书更完整.
    superbear
        25
    superbear  
       Apr 16, 2015
    callback里的this没有这属性,this此时指向的是window。楼上很多大牛
    neone
        26
    neone  
       Apr 16, 2015   ❤️ 2
    @sneezry JavaScript中函数没有签名,传入函数的参数可以通过局部变量arguments(类数组对象)访问到。
    @whatisnew 可以看看《JavaScript高级程序设计 第三版》的7.2.2关于this对象这一节,里面的例子和你这个问题差不多。
    200cc
        27
    200cc  
       Apr 16, 2015   ❤️ 1
    @whatisnew
    个人理解,oop的目的在于处理代码的复用性与可读性.效率的问题更依赖于或算法或运行环境来解决.

    至于你提到的new(_)什么什么的, 应该是你看的那段代码编写的不规范, 和prototype没关系啊. 推荐你去读一下阮一峰的博客:Javascript 面向对象编程, 深入浅出, 不能再赞.
    sneezry
        28
    sneezry  
       Apr 16, 2015 via iPhone
    @neone 受教😄
    whatisnew
        29
    whatisnew  
    OP
       Apr 16, 2015
    @200cc 找到了,不错不错!赞!
    hussion
        30
    hussion  
       Apr 16, 2015
    this.remove(); 非严格模式下,此处this指向的是window,严格模式下是null,所以,你懂得。。。
    jarlyyn
        31
    jarlyyn  
       Apr 16, 2015
    var self=this;

    this是js里比较蛋疼的一个坑。

    主要和使用回调/对象有关系,其实你用用call,apply,需要你制定thisarg就能明白了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   934 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 76ms · UTC 20:55 · PVG 04:55 · LAX 13:55 · JFK 16:55
    ♥ Do have faith in what you're doing.