Javascript this 的一些学习总结02【转自cnblogs的JKhuang】

本文深入探讨JavaScript中this关键字的工作原理及特殊场景应用,包括函数、构造函数调用时this值的变化,以及如何手动设置this值。

接上一篇Javascript this 的一些学习总结02【转自cnblogs的JKhuang】

引用类型以及this的null值

对于前面提及的情形,还有例外的情况,当调用表达式左侧是引用类型的值,但是this的值却是null,最终变为全局对象(global object)。 发生这种情况的条件是当引用类型值的base对象恰好为活跃对象(activation object)。

当内部子函数在父函数中被调用的时候就会发生这种情况,通过下面的示意代码介绍活跃对象:

// Declares foo function.
function foo() {
  function bar() {
    alert(this); // global
  }
  // The same as AO.bar().  
  bar();
}

由于活跃对象(activation object)总是会返回this值为——null(用伪代码来表示AO.bar()就相当于null.bar()),然后,this的值最终会由null转变为全局对象。

当函数调用包含在with语句的代码块中,并且with对象包含一个函数属性的时候,就会出现例外的情况。with语句会将该对象添加到作用域链的最前面,在活跃对象的之前。 相应地,在引用类型的值(标识符或者属性访问)的情况下,base对象就不再是活跃对象了,而是with语句的对象。另外,值得一提的是,它不仅仅只针对内部函数,全局函数也是如此, 原因就是with对象掩盖了作用域链中更高层的对象(全局对象或者活跃对象):

函数作为构造器被调用时this的值

函数作为构造函数时,我们通过new操作符创建实例对象是,它会调用Foo()函数的内部[[Construct]]方法;在对象创建之后,会调用内部的[[Call]]方法,然后所有Foo()函数中this的值会设置为新创建的对象。

// Declares constructor
function Foo() {
  // The new object.
  alert(this);
  this.x = 10;
}
 
var foo = new Foo();
foo.x = 23;
alert(foo.x); // 23

手动设置函数调用时this的值

Function.prototype原型上定义了两个方法,允许手动指定函数调用时this的值。这两个方法分别是:.apply()和.call()。这两个方法都接受第一个参数作为调用上下文中this的值,而这两个方法的区别是传递的参数,对于.apply()方法来说,第二个参数接受数组类型(或者是类数组的对象,比如arguments), 而.call()方法接受任意多的参数(通过逗号分隔);这两个方法只有第一个参数是必要的——this的值。

通过示例代码介绍call()方法和apply()方法的使用:

var myObject = {};
 
var myFunction = function(param1, param2) {
    
  //setviacall()'this'points to my Object when function is invoked
  this.foo = param1;
  this.bar = param2;
    
  //logs Object{foo = 'foo', bar = 'bar'}
  console.log(this); 
};
 
// invokes function, set this value to myObject
myFunction.call(myObject, 'foo', 'bar'); 

// logs Object {foo = 'foo', bar = 'bar'}
console.log(myObject);

call()方法第一个参数是必要的this值,接着我们可以传递任意多个参数,接着介绍apply()方法的使用。

var myObject = {};
 
var myFunction = function(param1, param2) {
    
  //set via apply(), this points to my Object when function is invoked
  this.foo=param1;
  this.bar=param2;
    
  // logs Object{foo='foo', bar='bar'}  
  console.log(this); 
};
 
// invoke function, set this value
myFunction.apply(myObject, ['foo', 'bar']); 

// logs Object {foo = 'foo', bar = 'bar'}
console.log(myObject); 

通过与call()方法对比,我们发现apply()方法和call()方法没有太大的区别,只是方法签名不一样。

总结

本文介绍Javascript中this的使用,更重要的是帮助我们能更好地理解this值在全局、函数、构造函数以及一些特例的情况中值的变化。

对于在函数上下文中this的值是函数调用者提供并且由当前调用表达式的形式而定的。如果在调用括号()的左边有引用类型的值,那么this的值就会设置为该引用类型值的base对象。 所有其他情况下(非引用类型),this的值总是null。然而,由于null对于this来说没有任何意义,因此会隐式转换为全局对象。

对于特例情况,我们要记住赋值符、逗号操作符以及||逻辑表达式,会使this丢失原先的引用类型值,变成了函数类型,this的值就变成了全局对象了

参考

  1. http://dmitrysoshnikov.com/ec...英文版

  2. http://blog.goddyzhao.me/post... 译文

  3. https://net.tutsplus.com/tuto...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值