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动态加载三
Aug 22 Javascript
在Javascript中 声明时用&quot;var&quot;与不用&quot;var&quot;的区别
Apr 15 Javascript
深入探讨JavaScript String对象
Mar 09 Javascript
jQuery实现图像旋转动画效果
May 29 Javascript
Web纯前端“旭日图”实现元素周期表
Mar 10 Javascript
vue中页面跳转拦截器的实现方法
Aug 23 Javascript
vue-prop父组件向子组件进行传值的方法
Mar 01 Javascript
BootStrap模态框闪退问题实例代码详解
Dec 10 Javascript
微信小程序的mpvue框架快速上手指南
May 15 Javascript
通过实例学习React中事件节流防抖
Jun 17 Javascript
p5.js绘制旋转的正方形
Oct 23 Javascript
JS轻量级函数式编程实现XDM二
Jun 16 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如何得到当前页和上一页的地址?
2006/11/27 PHP
PHP初学者最感迷茫的问题小结
2010/03/27 PHP
Thinkphp中volist标签mod控制一定记录的换行BUG解决方法
2014/11/04 PHP
一个轻量级的javascript库 pj介绍
2010/12/19 Javascript
Jquery中ajax方法data参数的用法小结
2014/02/12 Javascript
推荐8款jQuery轻量级树形Tree插件
2014/11/12 Javascript
网站申请不到支付宝接口、微信接口,免接口收款实现方式几种解决办法
2016/12/14 Javascript
Node.js操作redis实现添加查询功能
2017/05/25 Javascript
使用Bootstrap4 + Vue2实现分页查询的示例代码
2017/12/21 Javascript
浅谈vue引用静态资源需要注意的事项
2018/09/28 Javascript
小程序识别身份证,银行卡,营业执照,驾照的实现
2019/11/05 Javascript
使用JavaScript和MQTT开发物联网应用示例解析
2020/08/07 Javascript
uniapp实现可以左右滑动导航栏
2020/10/21 Javascript
Vue+Element-U实现分页显示效果
2020/11/15 Javascript
[36:41]完美世界DOTA2联赛循环赛FTD vs Magma第一场 10月30日
2020/10/31 DOTA
python将xml xsl文件生成html文件存储示例讲解
2013/12/03 Python
Python的Django框架中自定义模版标签的示例
2015/07/20 Python
Python生成随机密码的方法
2017/06/16 Python
利用python批量给云主机配置安全组的方法教程
2017/06/21 Python
Python cookbook(数据结构与算法)对切片命名清除索引的方法
2018/03/13 Python
python读取并写入mat文件的方法
2019/07/12 Python
基于python3监控服务器状态进行邮件报警
2019/10/19 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
降低python版本的操作方法
2020/09/11 Python
接口自动化多层嵌套json数据处理代码实例
2020/11/20 Python
毕业生个人求职信范例分享
2013/12/17 职场文书
违纪检讨书2000字
2014/02/08 职场文书
人代会标语
2014/06/30 职场文书
2014年安全生产目标责任书
2014/07/23 职场文书
企业法人代表证明书
2015/06/18 职场文书
中秋节祝酒词
2015/08/12 职场文书
先进个人主要事迹怎么写
2015/11/04 职场文书
《这片土地是神圣的》教学反思
2016/02/16 职场文书
总结一些Java常用的加密算法
2021/06/11 Java/Android
PHP遍历数组的6种方式总结
2021/11/17 PHP
Android自定义scrollview实现回弹效果
2022/04/01 Java/Android