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 相关文章推荐
引用外部脚本时script标签关闭的写法
Jan 20 Javascript
Javascript玩转继承(二)
May 08 Javascript
Javascript中With语句用法实例
May 14 Javascript
JavaScript中利用Array和Object实现Map的方法
Jul 27 Javascript
javascript动态获取登录时间和在线时长
Feb 25 Javascript
详解基于javascript实现的苹果系统底部菜单
Dec 02 Javascript
VUE-Table上绑定Input通过render实现双向绑定数据的示例
Aug 27 Javascript
Node.js系列之发起get/post请求(2)
Aug 30 Javascript
vue中利用iscroll.js解决pc端滚动问题
Feb 15 Javascript
js实现随机抽奖
Mar 19 Javascript
基于element-ui封装可搜索的懒加载tree组件的实现
May 22 Javascript
js仿京东放大镜效果
Aug 09 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获取一段文本显示点阵宽度和高度的方法
2015/03/12 PHP
网页开发中的容易忽略的问题 javascript HTML中的table
2009/04/15 Javascript
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
JavaScript作用域链示例分享
2014/05/27 Javascript
js实现右下角提示框的方法
2015/02/03 Javascript
js中的面向对象入门
2017/03/06 Javascript
vue动态组件实现选项卡切换效果
2017/03/08 Javascript
JavaScript如何一次性展示几万条数据
2017/03/30 Javascript
如何在 Vue.js 中使用第三方js库
2017/04/25 Javascript
Angular4 中常用的指令入门总结
2017/06/12 Javascript
React通过父组件传递类名给子组件的实现方法
2017/11/13 Javascript
mpvue 如何使用腾讯视频插件的方法
2018/07/16 Javascript
Vue中保存数据到磁盘文件的方法
2018/09/06 Javascript
JS实现贪吃蛇游戏
2019/11/15 Javascript
[02:31]2018年度DOTA2最具人气选手-完美盛典
2018/12/16 DOTA
[01:07:02]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第三场 2月26日
2021/03/11 DOTA
python 图片验证码代码
2008/12/07 Python
使用python实现递归版汉诺塔示例(汉诺塔递归算法)
2014/04/08 Python
python实现连接mongodb的方法
2015/05/08 Python
利用Python如何生成随机密码
2016/04/20 Python
Python UnboundLocalError和NameError错误根源案例解析
2018/10/31 Python
python二分法查找算法实现方法【递归与非递归】
2019/12/06 Python
Python基于gevent实现高并发代码实例
2020/05/15 Python
python性能测试工具locust的使用
2020/12/28 Python
python中xlrd模块的使用详解
2021/02/01 Python
纽约著名的服装辅料来源:M&J Trimming
2017/07/26 全球购物
eBay德国站:eBay.de
2017/09/14 全球购物
非凡女性奢华谦虚风格:The Modist
2017/10/28 全球购物
法国二手手袋、手表和奢侈珠宝购物网站:Collector Square
2018/07/05 全球购物
旅游管理毕业生自荐书
2014/02/02 职场文书
机关班子查摆问题及整改措施
2014/10/28 职场文书
黄石寨导游词
2015/02/05 职场文书
退休教师追悼词
2015/06/23 职场文书
谢师宴家长答谢词
2015/09/30 职场文书
PyQt5 显示超清高分辨率图片的方法
2021/04/11 Python
基于Python实现一个春节倒计时脚本
2022/01/22 Python