你所不知道的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 

0 0
原创粉丝点击