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 相关文章推荐
Firefox div高度自适应
Apr 28 Javascript
Javascript 实现的数独解题算法网页实例
Oct 15 Javascript
js识别不同浏览器基于userAgent做判断
Jul 29 Javascript
jquery实现select选择框内容左右移动代码分享
Nov 21 Javascript
基于javascript实现动态显示当前系统时间
Jan 28 Javascript
bootstrap模态框垂直居中效果
Dec 03 Javascript
JS库之Waypoints的用法详解
Sep 13 Javascript
angularJS开发注意事项
May 26 Javascript
vue使用axios上传文件(FormData)的方法
Apr 14 Javascript
微信小程序template模板与component组件的区别和使用详解
May 22 Javascript
JavaScript内置对象math,global功能与用法实例分析
Jun 10 Javascript
vue抽出组件并传值实例
Jul 31 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
Win9x/ME下Apache+PHP安装配置
2006/10/09 PHP
将数字格式的计算结果转为汉字格式
2006/10/09 PHP
PHP 中文乱码解决办法总结分析
2009/07/30 PHP
php之CodeIgniter学习笔记
2013/06/17 PHP
javascript 获取元素样式必杀技
2014/05/04 Javascript
jQuery中:animated选择器用法实例
2014/12/29 Javascript
node.js require() 源码解读
2015/12/13 Javascript
基于jquery实现轮播特效
2016/04/22 Javascript
一种基于浏览器的自动小票机打印实现方案(js版)
2016/07/26 Javascript
js实现弹窗居中的简单实例
2016/10/09 Javascript
JavaScript之class继承_动力节点Java学院整理
2017/07/03 Javascript
JS实现websocket长轮询实时消息提示的效果
2017/10/10 Javascript
JavaScript常用数组操作方法,包含ES6方法
2020/05/10 Javascript
js数组去重的方法总结
2019/01/18 Javascript
Angular8 Http拦截器简单使用教程
2019/08/20 Javascript
JavaScript面向对象核心知识与概念归纳整理
2020/05/09 Javascript
JavaScript中的执行环境和作用域链
2020/09/04 Javascript
使用python 获取进程pid号的方法
2014/03/10 Python
简单了解Django模板的使用
2017/12/20 Python
Python使用Phantomjs截屏网页的方法
2018/05/17 Python
python 字符串和整数的转换方法
2018/06/25 Python
python全栈知识点总结
2019/07/01 Python
Python如何实现远程方法调用
2020/08/07 Python
python Timer 类使用介绍
2020/12/28 Python
HTML5中图片之间的缝隙完美解决方法
2017/07/07 HTML / CSS
德国婴儿推车和儿童安全座椅商店:BABYSHOP
2016/09/01 全球购物
新西兰最大的在线设计师眼镜店:SmartBuyGlasses新西兰
2017/10/20 全球购物
神话般的珠宝:Ross-Simons
2020/07/13 全球购物
大专自我鉴定范文
2013/10/23 职场文书
租赁协议书范本
2014/04/22 职场文书
班主任寄语2015
2015/02/26 职场文书
2015年秋季小班开学寄语
2015/05/27 职场文书
九年级数学教学反思
2016/02/17 职场文书
英文诗歌翻译方法(赏析)
2019/08/16 职场文书
关于 Python json中load和loads区别
2021/11/07 Python
python画条形图的具体代码
2022/04/20 Python