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 07 Javascript
Mootools 1.2教程 排序类和方法简介
Sep 15 Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
Jan 23 Javascript
JS检测输入字符是否包含非法字符的示例代码
Feb 11 Javascript
javascript中的原型链深入理解
Feb 24 Javascript
AngularJS中实现显示或隐藏动画效果的方式总结
Dec 31 Javascript
json实现添加、遍历与删除属性的方法
Jun 17 Javascript
深入理解(function(){... })();
Aug 16 Javascript
基于JavaScript实现评论框展开和隐藏功能
Aug 25 Javascript
vue2中使用less简易教程
Mar 27 Javascript
实例讲解vue源码架构
Jan 24 Javascript
vue router 组件的高级应用实例代码
Apr 08 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
基于mysql的论坛(1)
2006/10/09 PHP
php中遍历二维数组并以表格的形式输出的方法
2017/01/03 PHP
自制PHP框架之设计模式
2017/05/07 PHP
thinkPHP5 ACL用户权限模块用法详解
2017/05/10 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
Laravel5.5+ 使用API Resources快速输出自定义JSON方法详解
2020/04/06 PHP
javascript getElementsByName()的用法说明
2009/07/31 Javascript
javascript prototype原型操作笔记
2009/12/07 Javascript
jsPDF生成pdf后在网页展示实例
2014/01/16 Javascript
jQuery实现冻结表头的方法
2015/03/09 Javascript
javascript将json格式数组下载为excel表格的方法
2017/12/22 Javascript
jQuery实现提交表单时不提交隐藏div中input的方法
2019/10/08 jQuery
微信小程序可滑动月日历组件使用详解
2019/10/21 Javascript
JavaScript享元模式原理与用法实例详解
2020/03/09 Javascript
微信小程序使用前置摄像头拍照
2020/10/22 Javascript
python实现一次创建多级目录的方法
2015/05/15 Python
Python中的index()方法使用教程
2015/05/18 Python
Python中functools模块函数解析
2017/03/12 Python
基于Django与ajax之间的json传输方法
2018/05/29 Python
python实现排序算法解析
2018/09/08 Python
python实现文本进度条 程序进度条 加载进度条 单行刷新功能
2019/07/03 Python
python设计tcp数据包协议类的例子
2019/07/23 Python
python 读txt文件,按‘,’分割每行数据操作
2020/07/05 Python
CSS3 绘制BMW logo实的现代码
2013/04/25 HTML / CSS
基于HTML5 Canvas:字符串,路径,背景,图片的详解
2013/05/09 HTML / CSS
Expedia丹麦:全球领先的旅游网站
2018/03/18 全球购物
Black Halo官方网站:购买连衣裙、礼服和连体裤
2018/06/13 全球购物
英国女性时尚鞋类的潮流制造者:Koi Footwear
2018/10/19 全球购物
Nip + Fab官网:英国美容品牌
2019/08/26 全球购物
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
业务员岗位职责范本
2013/12/15 职场文书
医学生自我评价
2014/01/27 职场文书
消防先进事迹材料
2014/02/10 职场文书
优秀研究生主要事迹
2014/06/03 职场文书
学校火灾防控方案
2014/06/09 职场文书
诚实守信演讲稿
2014/09/01 职场文书