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 相关文章推荐
fix-ie5.js扩展在IE5下不能使用的几个方法
Aug 20 Javascript
一个简单的网站访问JS计数器 刷新1次加1次访问
Sep 20 Javascript
用js获取电脑信息(是使用与IE浏览器)
Jan 15 Javascript
jquery.qrcode在线生成二维码使用示例
Aug 21 Javascript
JavaScript中检测变量是否存在遇到的一些问题
Nov 11 Javascript
利用函数的惰性载入提高javascript代码执行效率
May 05 Javascript
javascript实现window.print()去除页眉页脚
Dec 30 Javascript
如何使用JS在HTML中自定义字符串格式化
Jul 20 Javascript
Redux实现组合计数器的示例代码
Jul 04 Javascript
深入理解Promise.all
Aug 08 Javascript
小程序实现页面顶部选项卡效果
Nov 06 Javascript
解决VUE双向绑定失效的问题
Oct 29 Javascript
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
php数组应用之比较两个时间的相减排序
2008/08/18 PHP
PHP判断图片格式的七种方法小结
2013/06/03 PHP
php实现的漂亮分页方法
2014/04/17 PHP
PHP MYSQL简易交互式站点开发
2016/12/27 PHP
PHP论坛实现积分系统的思路代码详解
2020/06/01 PHP
一步一步教你写一个jQuery的插件教程(Plugin)
2009/09/03 Javascript
基于jquery的一个简单的脚本验证插件
2010/04/05 Javascript
js实现动态添加、删除行、onkeyup表格求和示例
2013/08/18 Javascript
JQuery教学之性能优化
2014/05/14 Javascript
AngularJS 路由详解和简单实例
2016/07/28 Javascript
AngularJS之页面跳转Route实例代码
2017/03/10 Javascript
input 标签实现输入框带提示文字效果(两种方法)
2017/10/09 Javascript
AngularJS实现的select二级联动下拉菜单功能示例
2017/10/25 Javascript
React Native使用Modal自定义分享界面的示例代码
2017/10/31 Javascript
django使用channels2.x实现实时通讯
2018/11/28 Javascript
对Layer UI 模块化的用法详解
2019/09/26 Javascript
解决vue 子组件修改父组件传来的props值报错问题
2019/11/09 Javascript
python使用paramiko模块实现ssh远程登陆上传文件并执行
2014/01/27 Python
python脚本实现验证码识别
2018/06/07 Python
TensorFlow 滑动平均的示例代码
2018/06/19 Python
python交互模式下输入换行/输入多行命令的方法
2019/07/02 Python
Python实现bilibili时间长度查询的示例代码
2020/01/14 Python
new_zeros() pytorch版本的转换方式
2020/02/18 Python
python读取mysql数据绘制条形图
2020/03/25 Python
django列表筛选功能的实现代码
2020/03/27 Python
python中_del_还原数据的方法
2020/12/09 Python
比利时家具购买网站:Home24
2019/01/03 全球购物
欧克利英国官网:Oakley英国
2019/08/24 全球购物
全球领先的在线cosplay服装商店:RoleCosplay
2020/01/18 全球购物
将一个数的从第5位开始的7个数取出,其余位置0
2016/05/26 面试题
志愿者爱心公益活动策划方案
2014/09/15 职场文书
圣诞节开幕词
2015/01/29 职场文书
只需要这一行代码就能让python计算速度提高十倍
2021/05/24 Python
python四个坐标点对图片区域最小外接矩形进行裁剪
2021/06/04 Python
dubbo服务整合zipkin详解
2021/07/26 Java/Android
zabbix如何添加监控主机和自定义监控项
2022/08/14 Servers