详解JavaScript中this关键字的用法
来源: 阅读:691 次 日期:2016-06-20 17:04:53
温馨提示: 小编为您整理了“详解JavaScript中this关键字的用法”,方便广大网友查阅!

this是函数内部的对象并且被用于调用该函数,this在全局中的使用非常之灵活,下面就带大家来详解JavaScript中this关键字的用法

this是函数内部的一个特殊对象,this引用的是函数据以执行的环境对象(关于环境对象我们会在文章最后作补充说明),在调用函数前this的值并不确定,不同的调用方式会导致this值的改变。

window.num = 22;

var o = {num: 11};

function sayNum(){

  alert(this.num)

}

sayNum();//22

o.sayNum = sayNum;

o.sayNum();//11

记住:函数名仅仅是一个包含指针的变量而已。因此即使是在不同的环境中执行,全局的sayNum()函数与o.sayNum()指向的仍然是同一个函数。

1.全局作用域中调用函数时

全局作用域中调用,this对象引用的是window

匿名函数的执行具有全局性,因此其this对象通常也指向window

function fn1(){

  console.log(this);

}

fn1();

2.通过new操作符调用

this引用的是实例对象

function Person(name){

  this.name = name;

}

Person.prototype.printName = function(){

  alert(this.name);//Byron

};

var p1 = new Person('Byron');

3.作为对象的方法调用

this引用的是该对象

var obj1 = {

  name: 'Byron',

  fn : function(){

    console.log(this);

  }

};

obj1.fn();

4.间接调用

call和apply

每个函数都包含两个非继承而来的方法:call()和apply()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。也就是说,直接调用函数,调用时指定执行环境是谁

window.color = 'red';

var o = {color: 'blue'};

function sayColor(){

  alert(this.color);

}

sayColor.call(this);//red

sayColor.call(window);//red

sayColor.call(o);//blue

(1)apply方法

接收两个参数,一个是在函数中运行函数的作用域,另一个是参数数组。

(2)call方法

call方法与apply方法相同,区别在于接收参数的方式不同,对于call方法而言,第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。

function fn(){

   console.log(this)//windwow

   function InnerFn(){

     console.log(this)

   }

   InnerFn.call(this)//window

}

fn();

 function fn0(){

   console.log(this)//window

}

function fn1(){

   fn0.call(this);

   console.log(this);//window

}

fn1();

function fn0(){

 console.log(this)//object

}

var o = {

  fn1: function fn1(){

    fn0.call(this);

    console.log(this);//object

  }

}

o.fn1();  

5.bind方法

这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。也就是说会返回一个新函数,并且使函数内部的this为传入的第一个参数

window.color = 'red';

var o = {color : 'blue'};

function sayColor(){

  alert(this.color)

}

var objectSayColor = sayColor.bind(o);

objectSayColor();//blue

补充说明:执行环境定义

定义了变量或者函数有权访问的其他数据,每个执行环境都有一个与之相关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。我们编写的代码无法访问这个对象,但解析器会在处理数据时在后台使用它。

一、执行环境的创建:

1.全局执行环境

在web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。代码载入浏览器时,全局执行环境被创建(当我们关闭网页或者浏览器时全局执行环境才被销毁)。

2.局部执行环境

每个函数都有自己的执行环境,因此局部执行环境为函数对象。当函数被调用时函数的局部环境被创建(函数内的代码执行完毕后,该环境被销毁,同时保存在其中的所有变量和函数定义也随之被销毁)。

这个执行环境以及相关的变量对象是个抽象的概念,解释如下

var a = 1;

function fn(num1,num2){

  var b = 2;

  function fnInner(){

    var c = 3;

    alert(a + b + c);

  }

  fnInner();//fnInner调用时局部执行环境创建

}

fn(4,5);//fn调用时局部执行环境创建

名单

二、作用域链

javascript函数的执行用到了作用域链,这个作用域链是函数定义的时候创建的,当定义一个函数时,它实际保存一个作用域链。当调用这个函数时,它创建一个新的对象来存储它的局部变量,并将这个对象添加至保存的作用域链。作用域链的前端始终都是当前执行的代码所在环境的变量对象。作用域链的末端始终都是全局执行环境的变量对象。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有权访问

var scope = 'global scope';

function checkscope(){

  var scope = 'local scope';

  function f(){return scope};

  return f;

}

checkscope()();//local scope

理解:当调用checkscope时,函数f被定义并作为局部变量绑定到了checkscope作用域链上,因此函数f无论在哪里调用,这种绑定依然有效,因此返回值为local scope。

var num1 = 1;

function Outer(){

  var num2 = 2;

  console.log(num1 + num2);//3

  function Inner(){

    //这里可以访问num3,num2,num1

    var num3 = 3;

    console.log(num1 + num2 + num3);//6

    }

  //这里可以访问num2,Inner(),num1但不能访问num3

  Inner();

}

Outer();

console.log(num1);//1,执行环境

//这里只能访问num1

作用域链(向上搜索):内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。

var name = 'Byron';

 function fn(){

   var name = 'Csper';

   console.log(name);//Casper

 }

 fn();

越往内部的环境,变量权重越高。

注意:没有带var关键字直接声明的变量属于全局变量如直接声明a = 1,此时的a为全局变量。

javscript引擎在进入作用域时,会对代码分两轮处理。第一轮,初始化变量。第二轮,执行代码

var a = 1;

function prison (a) {

  console.log(a);//1

  var a;

  console.log(a);//1

}

prison(1);

三、函数执行

函数调用进入执行环境时,首先处理arguments,初始化形参(默认值为undefined),然后初始化函数内的函数声明,当代码一步一步执行时再初始化函数内的变量声明(进入环境未开始执行代码时,值为undefined)。所以函数内的初始化顺序为形参,函数声明,变量声明。可以从上图图一看出。下面我来举个例子(整个全局环境也是函数)。

alert(typeof fn);//function,函数声明提前

alert(typeof fn0);//undefined,变量声明提前但未赋值

function fn(){

//函数表达式

}

var fn0 = function(){

//函数定义式

}

alert(typeof fn0);//function,此时变量已被赋值

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!

2025国考·省考课程试听报名

  • 报班类型
  • 姓名
  • 手机号
  • 验证码
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map