请教有一个 javascript 问题

2015-04-16 00:45:39 +08:00
 whatisnew

如代码代示,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;
});
3624 次点击
所在节点    JavaScript
31 条回复
Hyperion
2015-04-16 00:56:05 +08:00
调用this.edit 之前 _this = this;

在传入函数里使用_this.
ChiangDi
2015-04-16 00:59:31 +08:00
是报 this.remove 未定义吧?
sneezry
2015-04-16 01:17:53 +08:00
this.edit(id, function() {
this.remove(id);
}.bind(this));

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

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

不过,我在 `var obj {..}` 里 `console` 出来了 `this`,出来一个对象,是 `var obj` 声明的这个对象本身。
如果是 this 指向 window 的话,他应该有更多对象才对吧?
FrankFang128
2015-04-16 08:36:43 +08:00
@whatisnew 我上面说的是浏览器,所以用了极端两字。非浏览器的 this 会默认指向 null 或 global
FrankFang128
2015-04-16 08:37:46 +08:00
@whatisnew 你说的后半段我没看懂,贴出代码吧
mcfog
2015-04-16 08:37:47 +08:00
@FrankFang128 挑个刺,漏了strict mode哈
FrankFang128
2015-04-16 08:38:58 +08:00
@mcfog 嗯,“极端”。手机码字
FrankFang128
2015-04-16 08:43:13 +08:00
@mcfog 所以就简化了一些
Septembers
2015-04-16 08:54:19 +08:00
@mcfog ES5特性 ES3并没有
FrankFang128
2015-04-16 08:54:55 +08:00
现在有电脑了,就再说下吧。
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
2015-04-16 08:57:15 +08:00
不知道有没有说清楚,总之就是每看到一个 function 关键字,this 就有可能变化。
this 跟对象无关,只与 function 有关。
FrankFang128
2015-04-16 08:59:34 +08:00
17 楼说得有点乱,没看懂就忽略,看 18 楼吧。
whatisnew
2015-04-16 09:06:47 +08:00
@FrankFang128 懂了!哈哈,太赞了!新技能 get 高兴中

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/184016

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX