Javascript this 关键字 详解


Posted in Javascript onOctober 22, 2014

一、this指向构造函数实例化对象

在上篇文章中,我们提到了使用new和不使用new调用构造函数的区别,如下例:

function Benjamin(username, sex) {

    this.username = username;

    this.sex = sex;

}

var benjamin = new Benjamin("zuojj", "male");

//Outputs: Benjamin{sex: "male",username: "zuojj"}

console.log(benjamin);

var ben = Benjamin("zhangsan", "female");

//Outputs: undefined

console.log(ben);

当构造函数当做普通函数被调用时,并没有返回值,同时this指向全局对象。那么我们如何来避免因为缺少new关键字,而产生的问题呢?

function Benjamin(username, sex) {

 //Check whether "this" is a "Benjamin" object

 if(this instanceof Benjamin) {

     this.username = username;

     this.sex = sex;

 }else {

  return new Benjamin(username, sex);

 }

}

var benjamin = new Benjamin("zuojj", "male");

//Outputs: Benjamin{sex: "male",username: "zuojj"}

console.log(benjamin);

var ben = Benjamin("zhangsan", "female");

//Outputs: Benjamin {username: "zhangsan", sex: "female"} 

console.log(ben);

在上例中,我们首先检查this是否是Benjammin的实例,如果不是,使用new自动调用构造函数,并实例化,这意味着,我们不再需要担心,遗漏new关键字实例化构造函数。当然这样我们可能会养成一个坏的习惯,如果避免这种现象呢?我们可以抛出一个错误,像下面这样:

function Benjamin(username, sex) {

 //Check whether "this" is a "Benjamin" object

 if(this instanceof Benjamin) {

     this.username = username;

     this.sex = sex;

 }else {

  // If not, throw error.

        throw new Error("`Benjamin` invoked without `new`");

 }

}

二、this指向调用该函数的对象

看下面的例子:

var x = 10;

var obj = {

 x: 10,

 output: function() {

  //Outputs: true

  console.log(this === obj);

  return this.x;

 },

 innerobj: {

  x: 30,

  output: function() {

   //Outputs: true

   console.log(this === obj.innerobj);

   return this.x;

  }

 }

};

//Outputs: 10

console.log(obj.output());

//Outputs: 30

console.log(obj.innerobj.output());

三、this指向全局对象

在上面讨论构造函数的时候我们也讨论到不适用new的时候,this会指向全局对象,下面我们来看看两种常见的容易犯错的实例:

var x = 100;

var obj = {

 x: 10,

 output: function() {

  (function() {

   //Outputs: true

   console.log(this === window);

   //Outputs: Inner: 100

   console.log("Inner:" + this.x);

  })();

  

  return this.x;

 }

};

//Outputs: 10

console.log(obj.output());

在使用闭包的时候,作用域发生变化,this指向window(浏览器中)。

var x = 100;

var obj = {

 x: 10,

 output: function() {

  return this.x;

 }

};

var output = obj.output;

//Outputs: 10

console.log(obj.output());

//Outputs: 100

console.log(output());

var obj2 = {

 x: 30,

 output: obj.output

}

//Outputs: 30

console.log(obj2.output());

此时this始终指向函数调用时的对象。

四、this指向apply/call()方法指派的对象

var x = 100;

var obj = {

 x: 10,

 output: function() {

  return this.x;

 }

};

//Outputs: 10

console.log(obj.output());

var obj2 = {

 x: 40,

 output: obj.output

}

//Outputs: 40

console.log(obj.output.call(obj2));

//Outputs: 10

console.log(obj2.output.apply(obj));

五、callback函数?鹊?his指向调用该callback的函数的this所指向的对象

//<input type="text" value="3" id="txt_username">

$("#username").on("click", function() {

 console.log(this.value);

});

六、Function.prototype.bind中的this

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
实例一:

function person() {

 return this.name;

}

//Function.prototype.bind

var per = person.bind({

 name: "zuojj"

});

console.log(per);

var obj = {

 name: "Ben",

 person: person,

 per: per

};

//Outputs: Ben, zuojj

console.log(obj.person(), obj.per());

实例二:

this.x = 9; 

var module = {

  x: 81,

  getX: function() { return this.x; }

};

//Outputs: 81

console.log(module.getX()); 

var getX = module.getX;

//Outputs: 9, because in this case, "this" refers to the global object

console.log(getX); 

// create a new function with 'this' bound to module

var boundGetX = getX.bind(module);

//Outputs: 81

console.log(boundGetX());
Javascript 相关文章推荐
JavaScript和ActionScript的交互实现代码
Aug 01 Javascript
onkeypress字符按键兼容所有浏览器使用介绍
Apr 24 Javascript
JS 实现图片直接下载示例代码
Jul 22 Javascript
基于javascript实现精确到毫秒的倒计时限时抢购
Apr 17 Javascript
快速使用node.js进行web开发详解
Apr 26 Javascript
vue中appear的用法
Aug 17 Javascript
vue+vuecli+webpack中使用mockjs模拟后端数据的示例
Oct 24 Javascript
JavaScript之实现一个简单的Vue示例
Jan 17 Javascript
微信小程序访问豆瓣电影api的实现方法
Mar 31 Javascript
axios异步提交表单数据的几种方法
Aug 11 Javascript
JavaScript进阶(三)闭包原理与用法详解
May 09 Javascript
使用vue-element-admin框架从后端动态获取菜单功能的实现
Apr 29 Vue.js
Javascript 构造函数详解
Oct 22 #Javascript
Javascript中Array.prototype.map()详解
Oct 22 #Javascript
javascript数组详解
Oct 22 #Javascript
Javascript 数组排序详解
Oct 22 #Javascript
Javascript中arguments对象详解
Oct 22 #Javascript
Javascript中的默认参数详解
Oct 22 #Javascript
js style动态设置table高度
Oct 21 #Javascript
You might like
《超神学院》霸气归来, 天使彦上演维多利亚的秘密
2020/03/02 国漫
在PHP中使用FastCGI解析漏洞及修复方案
2015/11/10 PHP
详解WordPress中的头像缓存和代理中的缓存更新方法
2016/03/01 PHP
php实现单笔转账到支付宝功能
2018/10/09 PHP
jquery load()在firefox(火狐)下显示不正常的解决方法
2011/04/05 Javascript
jQuery列表拖动排列具体实现
2013/11/04 Javascript
javascript event在FF和IE的兼容传参心得(绝对好用)
2014/07/10 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
Vue.js每天必学之数据双向绑定
2016/09/05 Javascript
js实现点击图片自动提交action的简单方法
2016/10/16 Javascript
jQuery事件对象总结
2016/10/17 Javascript
js实现打地鼠小游戏
2017/02/13 Javascript
JavaScript中的this陷阱的最全收集并整理(没有之一)
2017/02/21 Javascript
Angular4学习教程之HTML属性绑定的方法
2018/01/04 Javascript
vue router 源码概览案例分析
2018/10/09 Javascript
微信小程序实现折线图的示例代码
2019/06/07 Javascript
vue如何使用async、await实现同步请求
2019/12/09 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)
2020/08/28 Javascript
[11:12]2018DOTA2国际邀请赛寻真——绿色长城OpTic
2018/08/10 DOTA
探究Python的Tornado框架对子域名和泛域名的支持
2015/05/02 Python
python方向键控制上下左右代码
2018/01/20 Python
python实现猜单词小游戏
2020/05/22 Python
利用Python进行图像的加法,图像混合(附代码)
2019/07/14 Python
django框架中间件原理与用法详解
2019/12/10 Python
python 生成任意形状的凸包图代码
2020/04/16 Python
python实现扫雷小游戏
2020/04/24 Python
购买限量版收藏品、珠宝和礼品:Bradford Exchange
2016/09/23 全球购物
一个精品风格的世界:Atterley
2019/05/01 全球购物
女大学生自我鉴定
2013/12/09 职场文书
农民致富事迹材料
2014/01/23 职场文书
高中军训第一天感言
2014/03/06 职场文书
2014年统战工作总结
2014/12/09 职场文书
中学社团活动总结
2015/05/07 职场文书
2015小学教师年度考核工作总结
2015/05/12 职场文书
pandas进行数据输入和输出的方法详解
2022/03/23 Python