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 相关文章推荐
IE浏览器兼容Firefox的JS脚本的代码
Oct 23 Javascript
JavaScript 程序编码规范
Nov 23 Javascript
JS实现的省份级联实例代码
Jun 24 Javascript
在页面中js获取光标/鼠标的坐标及光标的像素坐标
Nov 11 Javascript
基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js详解
Mar 05 Javascript
jqGrid表格应用之新增与删除数据附源码下载
Dec 02 Javascript
jquery.picsign图片标注组件实例详解
Feb 02 jQuery
Vue弹出菜单功能的实现代码
Sep 12 Javascript
JavaScript错误处理操作实例详解
Jan 04 Javascript
深入学习js函数的隐式参数 arguments 和 this
Jun 24 Javascript
基于vue-draggable 实现三级拖动排序效果
Jan 10 Javascript
微信小程序实现身份证取景框拍摄
Sep 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&amp;MYSQL留言板源码
2020/07/19 PHP
在PHP中读取和写入WORD文档的代码
2008/04/09 PHP
php对图像的各种处理函数代码小结
2013/07/08 PHP
PHP JS Ip地址及域名格式检测代码
2013/09/27 PHP
php检查日期函数checkdate用法实例
2015/03/19 PHP
php隐藏实际地址的文件下载方法
2015/04/18 PHP
Laravel5.5+ 使用API Resources快速输出自定义JSON方法详解
2020/04/06 PHP
详解PHP中的8个魔术常量
2020/07/06 PHP
PHP反射基础知识回顾
2020/09/10 PHP
(推荐一个超好的JS函数库)S.Sams Lifexperience ScriptClassLib
2007/04/29 Javascript
基于jquery的放大镜效果
2012/05/30 Javascript
跨域传值即主页面与iframe之间互相传值
2013/12/09 Javascript
jquery制作居中遮罩层效果分享
2014/02/21 Javascript
javascript检测是否联网的实现代码
2014/09/28 Javascript
JavaScript编程中window的location与history对象详解
2015/10/26 Javascript
微信小程序 input输入框详解及简单实例
2017/01/10 Javascript
React项目动态设置title标题的方法示例
2018/09/26 Javascript
jQuery实现适用于移动端的跑马灯抽奖特效示例
2019/01/18 jQuery
在Python的列表中利用remove()方法删除元素的教程
2015/05/21 Python
Python中如何获取类属性的列表
2016/12/26 Python
用pickle存储Python的原生对象方法
2017/04/28 Python
Python实现将一个正整数分解质因数的方法分析
2017/12/14 Python
python3+PyQt5自定义视图详解
2018/04/24 Python
numpy.linspace 生成等差数组的方法
2018/07/02 Python
代码实例讲解python3的编码问题
2019/07/08 Python
如何高效率的查找一个月以内的数据
2012/04/15 面试题
应届生保险求职信
2013/11/11 职场文书
应届生自荐书
2014/06/23 职场文书
超市创业计划书
2014/09/15 职场文书
乡镇干部先进性教育活动个人整改措施
2014/09/16 职场文书
检讨书范文
2015/01/27 职场文书
2015年求职自荐信范文
2015/03/04 职场文书
CSS3实现的水平标题菜单
2021/04/14 HTML / CSS
css中z-index: 0和z-index: auto的区别
2021/08/23 HTML / CSS
Java中CyclicBarrier和CountDownLatch的用法与区别
2021/08/23 Java/Android
Python OpenCV超详细讲解调整大小与图像操作的实现
2022/04/02 Python