javascript中this关键字详解(2)

构造函数创建的三个基本要求:函数名首字母大写;构造函数内部使用this关键字来指向即将生成的对象实例;使用new关键字来调用构造函数并返回对象实例。

如果想更进一步深入了解构造函数与new关键字的关系,请移步至 这篇文章 。

2.3:对象的方法

当A对象的方法被赋予B对象,该方法中的this就从指向A对象变成指向B对象。所以要特别小心,将某个对象的方法赋值个另外一个对象时,会改变this的指向。

var keith = { sex: 'boy', foo: function() { return this.sex; } }; var rascal = { sex: 'girl' }; rascal.foo = keith.foo; console.log(keith.foo()); //'boy' console.log(rascal.foo()); //'girl'

上面代码中,把keith的foo函数赋值给了rascal,那么this的指向就从keith变成了rascal。

如果某个方法位于多层对象的内部,这时为了简化书写,把该方法赋值给一个变量,往往会得到不一样的结果。

var a = { b: { p: 'keith', c: function() { return this.p; } } }; var person = a.b.c; console.log(person()); //undefined

上面代码中,c是两层对象里面的一个方法。为求简便,将其赋值给全局变量person,结果调用时,this指向了顶层对象window。而在window中变量p默认值为undefined。

要解决这个问题,可以只将c所在的对象赋值给person变量,或者是直接调用。

var person = a.b; console.log(person.c()); //'keith' console.log(a.b.c()); //'keith'

3.使用注意点

3.1:避免多层嵌套this

当在闭包中使用多层this,则this都会指向window。

function keith() { console.log(this); return function() { return this; } } keith(); //window keith()(); //window

上面代码中,在一个函数中返回另外一个匿名函数是闭包的特点之一,可以看出,当在闭包中使用this对象都会指向全局作用域中的window对象。

如果在函数外包含一个对象,则内部this指向全局作用域,而外部this对象指向当前作用域。

var o = { f1: function() { console.log(this); (function() { console.log(this) })(); } }; o.f1(); //Object , Window

上面代码包含两层this,结果运行后,第一层指向当前对象,第二层指向全局对象。

实际执行的是如下代码。

function keith() { console.log(this); } var o = { f1: function() { console.log(this); var f2 = keith(); } }; o.f1(); //Object , Window

要实现多层this嵌套,有两种解决方法:

一是在第二层中改用一个指向外层this的变量。

var o = { f1: function() { console.log(this); var that = this; (function() { console.log(that); })(); } }; o.f1(); //Object , Object

上面代码中,定义了局部变量that,固定指向了外层的this,然后在内层中使用that,就不会发生this指向的改变。但是如果函数外部内有嵌套一个对象,this还是会指向全局。

二是Javascript中的严格模式。在严格模式下,如果内部函数的this指向了window对象,就会报错。

var a = { count: 0, fun: function() { 'use strict'; return this.count++; } } var f = a.fun; console.log(f()) //'TypeError: this is undefined'

上面代码中,fun方法使用严格模式声明。把a对象中的fun方法赋值给全局变量f,那么this此时指向window对象,在严格模式下,就会报错。如果函数外部没有嵌套一个对象,那么不会报错,而是会返回undefined。

3.2:避免数组处理方法中的this

数组的map和foreach方法,允许提供一个函数作为参数。这个函数内部不应该使用this

var keith = { a: 'Hello', b: ['b1', 'b2'], c: function() { this.b.forEach(function(item) { console.log(this.a + ' ' + item); }) } }; keith.c(); //undefined b1 //undefined b2

上面代码中,forEach方法的回调函数中的this,其实指向的是window对象,因此取不到keith.a的值,同上也属于避免多层嵌套this。也就是说,内层的this不指向外部函数,而是指向顶层对象。

要解决这个方法,可以使用that变量来代替回调函数中的this。

var keith = { a: 'Hello', b: ['b1', 'b2'], c: function() { var that = this; this.b.forEach(function(item) { console.log(that.a + ' ' + item); }) } }; keith.c(); //Hello b1 //Hello b2

另外一种方法,就是让this做为forEach方法的第二个参数,来固定它的运行环境。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwfjgw.html