美文网首页
JS中的this

JS中的this

作者: 汤汤汤不乐 | 来源:发表于2019-02-02 21:23 被阅读0次

参考书籍:《JavaScript设计模式与开发实践》;
《JavaScript高级程序设计(第3版)》(以下简称《高级程序设计》)

JS的this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被某个对象的方法调用时,this等于那个对象。
除去不常用的with和eval的情况,具体到实际应用中 ,this的指向大致可以分为以下4种(其中还包含一些特殊情况需要被提及)。

1、作为对象的方法调用
//作为对象调用时,this指向这个对象
var obj = {
    getA : function(){
          alert ( this === obj );  
    }
}

obj.getA();  // true 
2、作为普通函数调用

当函数不作为对象的属性调用时,也就是常说的用普通函数方式调用,此时的this总是指向全局对象。在浏览器中,这个全局对象是window对象。

window.name = 'globalName';

var getName = function(){
       return this.name;
}
console.log( getName() ); // globalName

上面这个例子直接创建了一个函数并在全局调用,事实上,还可以将对象中的函数赋值给全局中的函数,请看如下代码:

//与上一段代码效果相同
window.name = 'globalName';
var obj = {
      name : 'sven',
      getName : function(){
              return this.name;
      }
}
var getName = obj.getName;
console.log( getName() ); // globalName

神奇的是,如果将对象中的函数赋值给对象中的函数,this还是会指向全局:

var name = "globalName";
var obj = {
    name: "sven",
    getName: function() {
        return this.name;
    }
};
console.log((obj.getName = obj.getName)()); // globalName (非严格模式下)

这是在《高级程序设计》第183页的一个例子。书本中的解释为:(函数调用时的)这行代码先执行了一条赋值语句,然后再调用赋值后的结果。因为这个赋值表达式的值是函数本身,所以this的值不能得到维持,结果就返回了"globalName"。要详细解释这个问题,网上有一篇文章可以参考:《 this在方法赋值过程中无法保持(隐式丢失)

简单点想,以上这些都可看作普通函数在全局中调用,this自然是指向全局的。这也充分说明了之前提到的:JS的this对象是在运行时基于函数的执行环境绑定的,与函数声明时的环境无关。

除此之外,常常会出现函数内部嵌套函数的情况,匿名函数作为内部函数很常见。
关于匿名函数,《高级程序设计》中说,“匿名函数的执行环境具有全局性,因此其this对象通常指向window”。然而经过测试发现,函数内部的非匿名函数也是指向window的:

var name ="Window";
var obj={};
      
obj.Outer = function(){
    function Inner(){
        console.log(this.name);  //"Window" (非严格模式);"undefined"(严格模式)
    }
    Inner();  
 }
      
obj.Outer(); 

内部函数在搜索this时,只会搜索到其活动对象为止,而其活动对象位于作用域链的前端,因此永远不能直接访问外部函数中的this,而是将它指向了全局对象。若是内部函数需要访问外部this,通常会这样处理:

var name ="Window";
var obj={
     name : "outerName"
};
      
obj.Outer = function(){
     var that = this;
     function Inner(){
      console.log(that.name);  // outerName
     }
     Inner();
}
obj.Outer(); 
3、构造器调用

在js中,可以使用new运算符调用函数,此时的函数被当作一个构造函数,而构造器中的this就指向返回的对象:

var MyClass = function(){
      this.name =  'sven';
 }

var obj = new MyClass();
console.log( obj.name );   // 输出:sven

如果构造器显式地返回一个object类型对象,则运算结果为最终返回的对象:

var MyClass = function(){
      this.name =  'sven';
      return {
          name: 'anne'
       }
 }

var obj = new MyClass();
console.log( obj.name );   // 输出:anne

若是返回非对象类型的数据,就不会造成上述问题:

var MyClass = function(){
      this.name =  'sven' ;
      return 'anne' ;
 }

var obj = new MyClass();
console.log( obj.name );   // 输出:sven
4、call、apply调用

call、apply可以动态改变传入函数的this:

var obj1 = {
     name: 'sven',
     getName: function(){
           return this.name;
     }
};

var obj2 = {
      name: 'anne'
}
console.log( obj1.getName.call(obj2) );  // 输出:anne

call、apply这两个函数很强大,它扩充了函数赖以运行的作用域,实现了对象和方法的解耦。call 和 apply 方法能很好地体现 JavsScript 的函数式语言特性,在 JavsScript 中,几乎每一次编写函数式语言语言风格的代码都离不开call和apply。常用的js原型继承模式,以及js诸多版本的设计模式中,都用到了它们。

相关文章

  • JavaScript 04 (do...while循环/for

    js循环,js循环嵌套,js do...while循环,js的for循环,js中的break,js中的contin...

  • iOS原生&JS交互

    OC 获取js中的key OC调用js方法 JS调用OC中不带参数的block JS调用OC中带参数的block ...

  • JS 对象

    JS对象 JS对象的意义和声明 在JS中,对象(OBJECT)是JS语言的核心概念,也是最重要的数据类型。在JS中...

  • 单引号和双引号

    JS中 js中单引号和双引号的区别(html中属性规范是用双引号,js中字符串规定是用单引号)(js中单引号区别和...

  • js中的this

    一句话,call的第一个参数 看几个例子例1. 这里的this是什么?不要靠猜,是call的第一个参数,不知道去看...

  • js 中的this

    首先js中函数的this在函数被调用时总是指向一个对象(this对象是在运行时基于函数的执行环境绑定的) 然后 它...

  • JS中的this

    JS中的this 众所周知,JS中this的代表的是当前函数调用者的上下文。JS是解释性的动态类型语言,函数在调用...

  • js中的!!

    !!一般用来将后面的表达式强制转换为布尔类型的数据(boolean),也就是只能是true或者false。 var...

  • js中的this

    目标:js中this的指向? 问题的引出 指出this指向什么 js中函数的三种调用形式 func(p1, p2)...

  • JS中的this

    初学JavaScript经常被this绕晕,所以我总结一下JavaScript中的this。首先声明本文讨论的是非...

网友评论

      本文标题:JS中的this

      本文链接:https://www.haomeiwen.com/subject/jdxhsqtx.html