你所不知道的JavaScript(一)this 关键字
来源:互联网 发布:埃博拉病毒 知乎 编辑:程序博客网 时间:2024/04/28 04:45
比起Java, C#等面向对象语言,this关键字在JS中有更多需要注意和理解的地方,下面就来一一看下几个场景的用法:
1. 跟 Java, C#等语言一样,this可以声明在构造函数里,用来定义成员变量
function foo(a) {this.a = a;}var bar = new foo( 2 );console.log( bar.a ); // 2
2. 如果不是作为new 的构造函数, this代表的是当前上下文的对象
function foo(num) { console.log( "foo: " + num ); this.count++;}foo.count = 0;var i;for (i=0; i<10; i++) { if (i > 5) { foo( i ); }}// foo: 6// foo: 7// foo: 8// foo: 9console.log( foo.count ); // 0
上面的代码,foo.count 和this.count 不是一个变量, 在默认模式下,this.count创建了一个全局的变量,由于没有初始化,在++后变成NaN。 而在strict mode下, this.count会在运行时直接抛出undefined的错误
3. 隐式改变this
function foo() {console.log( this.a );}var obj2 = {a: 42,foo: foo};var obj1 = {a: 2,obj2: obj2};obj1.obj2.foo(); // 42
this是当前上下文的对象,所以在obj1.obj2.foo()中,this指向的是obj2,所以this.a=obj2.a
4. 显式改变this
可以使用call, apply和bind三个方法来显示改变this
function foo() {console.log( this.a );}var obj = {a: 2};foo.call( obj ); // 2 obj并没有foo方法,使用foo.call把foo的强制绑定到obj的上下文function foo(something) {console.log( this.a, something );return this.a + something;}var obj = {a: 2};var bar = function() {return foo.apply( obj, arguments ); //带参数的强制硬性绑定,无论调用环境如何,都会使用 obj 作为调用上下文};var b = bar( 3 ); // 2 3//也可以用bind返回重新绑定过的函数,已供后面使用function foo(something) {console.log( this.a, something );return this.a + something;}var obj = {a: 2};var bar = foo.bind( obj );var b = bar( 3 ); // 2 3console.log( b ); // 5function foo(el) {console.log( el, this.id );}var obj = {id: "awesome"};// use `obj` as `this` for `foo(..)
call和apply的区别仅仅是apply支持传递参数
《你所不知道的JS》对this做了很好的总结,优先级如下:
1. 如果是用new创建的this,就是新对象的成员函数: var bar = new foo()
2. 如果使用了call, apply或bind, 则为显式绑定,this指向call, apply或bind方法的第一个参数: var bar = foo.call(obj2 )
3. 隐式绑定: var bar = obj1.foo()
4. 默认的绑定,在strict模式下抛出undefined, 在普通模式下会生成全局变量: var bar = foo()
好了,规则都说完了,下面这段代码如果搞明白了,说明对this 的理解也过关了:
function foo(something) { this.a = something;}var obj1 = { foo: foo};var a = 4;var obj2 = {};obj1.foo(2);console.log(obj1.a); foo(5);console.log(a); obj1.foo.call(obj2, 3);console.log(obj2.a); var bar = new obj1.foo(4);console.log(obj1.a); console.log(bar.a);
原文: https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch1.md
- 你所不知道的JavaScript(一)this 关键字
- 你不知道的JavaScript(四)this(一)
- JavaScript中的this(你不知道的JavaScript)
- JavaScript中的this(你不知道的JavaScript)
- JavaScript中的this(你不知道的JavaScript)
- JavaScript中的this(你不知道的JavaScript)
- 你不知道的javascript(一)
- [图解] 你不知道的 JavaScript - “this”
- [图解] 你不知道的 JavaScript - “this”
- 【图解】你不知道的 javascript “this”
- javascript你不知道的This
- this和对象——源自《你所不知道的JavaScript》
- JavaScript你所不知道的困惑(1)
- JavaScript你所不知道的困惑(2)
- JavaScript你所不知道的困惑(3)
- 你所不知道的Html5那些事(一)
- 你所不知道的继承(一)
- 你不知道的JavaScript(十)with关键字
- 简单的android闹钟
- 《现代礼仪》总结七
- Java异常处理的注意点总结
- linux命令记录
- 132 大谷 成運
- 你所不知道的JavaScript(一)this 关键字
- linux安全配置记录
- 第3方模块编译及一致性哈希应用
- Android学习2控件之Button按钮组件
- QEMU Emulator User Documentation
- 敏捷开发的一些理解
- Uva - 11988 - Broken Keyboard (a.k.a. Beiju Text)
- 做的一组实验
- String.Split方法的说明以及用法