如代码代示,js对象内访问,用 this
和 obj
都可以,但是在 对象方法内在 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;
});
1
Hyperion 2015-04-16 00:56:05 +08:00 2
调用this.edit 之前 _this = this;
在传入函数里使用_this. |
2
ChiangDi 2015-04-16 00:59:31 +08:00 via Android 1
是报 this.remove 未定义吧?
|
3
sneezry 2015-04-16 01:17:53 +08:00 2
this.edit(id, function() {
this.remove(id); }.bind(this)); 但是,this.edit不是只接受一个参数吗?? |
7
FrankFang128 2015-04-16 07:46:34 +08:00 via Android 1
极端得讲一下:
1 this 永远指向 window 2 除非你显式指定 this 3 显式地指定this有如下方法: 3.1 使用点语法指定,如obj.remove 3.2 使用call和apply指定 3.3 浏览器内置方法默认指定,如事件的回调等 3.4 其他不建议的方法 |
8
FrankFang128 2015-04-16 07:49:59 +08:00 via Android
不要再用OOP的角度来理解JS的this了,不然你永远学不会。
好好看看犀牛书,不要看了蝴蝶书就以为自己会JS了。 |
9
FrankFang128 2015-04-16 07:52:45 +08:00 via Android
3.2 还应加上 bind 等方法。
|
10
whatisnew OP @FrankFang128 果然大神,一看就知道我纠结在哪了,真的这么多年 cpp java php 习惯性 oop 了,着手码几行 js 真心不适应,正在强迫自己适应中。
从前端同事那里借了这个犀牛书,正在专研中!哈哈 不过,我在 `var obj {..}` 里 `console` 出来了 `this`,出来一个对象,是 `var obj` 声明的这个对象本身。 如果是 this 指向 window 的话,他应该有更多对象才对吧? |
11
FrankFang128 2015-04-16 08:36:43 +08:00 via Android
@whatisnew 我上面说的是浏览器,所以用了极端两字。非浏览器的 this 会默认指向 null 或 global
|
12
FrankFang128 2015-04-16 08:37:46 +08:00 via Android
@whatisnew 你说的后半段我没看懂,贴出代码吧
|
13
mcfog 2015-04-16 08:37:47 +08:00 via Android 1
@FrankFang128 挑个刺,漏了strict mode哈
|
14
FrankFang128 2015-04-16 08:38:58 +08:00 via Android
@mcfog 嗯,“极端”。手机码字
|
15
FrankFang128 2015-04-16 08:43:13 +08:00 via Android
@mcfog 所以就简化了一些
|
16
Septembers 2015-04-16 08:54:19 +08:00 via Android
@mcfog ES5特性 ES3并没有
|
17
FrankFang128 2015-04-16 08:54:55 +08:00 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 了(在这一句话被执行的时候) |
18
FrankFang128 2015-04-16 08:57:15 +08:00
不知道有没有说清楚,总之就是每看到一个 function 关键字,this 就有可能变化。
this 跟对象无关,只与 function 有关。 |
19
FrankFang128 2015-04-16 08:59:34 +08:00
17 楼说得有点乱,没看懂就忽略,看 18 楼吧。
|
20
whatisnew OP @FrankFang128 懂了!哈哈,太赞了!新技能 get 高兴中
|
21
200cc 2015-04-16 09:09:17 +08:00
js可以用prototype来实现oop.
感觉这样理解起来更容易. |
22
Hyperion 2015-04-16 09:11:09 +08:00 1
使用this 其实完全没有什么问题, 而且上面对this 的解释似乎有点小问题?
可以参考MDN 的这个链接, 似乎是有意漏掉了某个? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this Javascript 的this 不是难理解, 只是因为它本身的一组特性综合导致他和别的语言不一样. 关于在闭包里使用this , 我最早是从阮一峰的blog 上看到最完整的概述的. 效率问题, 都是引用. 作为一种习惯, 理解this 很重要, 因为这个已经是通行的做法了. 掏出犀牛书第六版(第五版没有在学校), p188页 译者注释. 仅作讨论, 求同存异. 希望不要引起争执. 书, 个人不提供建议, 自认水平有限. 犀牛这本圣经扫了几遍, 但看红皮还是有很多要补的地方, 比如逻辑操作符具体的特性, 各种实现类方式的利弊, 以及各种兼容实现问题. |
23
whatisnew OP @200cc prototype 实现的 oop 会有效率上的提升吗?因为我看到 prototype oop 在调用的时候太惨了 new(_) 那个下划线,那些个 find 真心觉得是乱码一样,比较难理解。
|
25
superbear 2015-04-16 09:45:28 +08:00
callback里的this没有这属性,this此时指向的是window。楼上很多大牛
|
26
neone 2015-04-16 10:16:54 +08:00 2
|
27
200cc 2015-04-16 10:25:54 +08:00 1
@whatisnew
个人理解,oop的目的在于处理代码的复用性与可读性.效率的问题更依赖于或算法或运行环境来解决. 至于你提到的new(_)什么什么的, 应该是你看的那段代码编写的不规范, 和prototype没关系啊. 推荐你去读一下阮一峰的博客:Javascript 面向对象编程, 深入浅出, 不能再赞. |
30
hussion 2015-04-16 10:44:05 +08:00
this.remove(); 非严格模式下,此处this指向的是window,严格模式下是null,所以,你懂得。。。
|
31
jarlyyn 2015-04-16 11:02:23 +08:00
var self=this;
this是js里比较蛋疼的一个坑。 主要和使用回调/对象有关系,其实你用用call,apply,需要你制定thisarg就能明白了。 |