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 相关文章推荐
JQuery 学习笔记 选择器之四
Jul 23 Javascript
javascript,jquery闭包概念分析
Jun 19 Javascript
js取消单选按钮选中并判断对象是否为空
Nov 14 Javascript
JS根据变量保存方法名并执行方法示例
Apr 04 Javascript
asp.net+js实现金额格式化
Feb 27 Javascript
深入理解node exports和module.exports区别
Jun 01 Javascript
JavaScript 限制文本框不可输入英文单双引号的方法
Dec 20 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
Jan 13 Javascript
vue2.0实战之使用vue-cli搭建项目(2)
Mar 27 Javascript
vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)
Oct 16 Javascript
浅谈webpack性能榨汁机(打包速度优化)
Jan 09 Javascript
详解JVM系列之内存模型
Jun 10 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
WinXP + Apache +PHP5 + MySQL + phpMyAdmin安装全功略
2006/07/09 PHP
PHP删除HTMl标签的三种解决方法
2013/06/30 PHP
qq登录,新浪微博登录接口申请过程中遇到的问题
2014/07/22 PHP
php实现的简单检验登陆类
2015/06/18 PHP
php文件上传你必须知道的几点
2015/10/20 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
2016/09/11 PHP
laravel实现按时间日期进行分组统计方法示例
2019/03/23 PHP
JavaScript和JQuery实用代码片段(一)
2010/04/07 Javascript
jquery 学习之二 属性(html()与html(val))
2010/11/25 Javascript
悄悄用脚本检查你访问过哪些网站的代码
2010/12/04 Javascript
基于jQuery的动态表格插件
2011/03/28 Javascript
Javascript 判断是否存在函数的方法
2013/01/03 Javascript
jquery序列化方法实例分析
2015/06/10 Javascript
两种js监听滚轮事件的实现方法
2016/05/13 Javascript
jQuery学习之DOM节点的插入方法总结
2017/01/22 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
React-native桥接Android原生开发详解
2018/01/17 Javascript
JavaScript时间日期操作实例小结【5个示例】
2018/12/22 Javascript
js作用域和作用域链及预解析
2019/04/11 Javascript
JS实现进度条动态加载特效
2020/03/25 Javascript
python实现telnet客户端的方法
2015/04/15 Python
Python获取linux主机ip的简单实现方法
2016/04/18 Python
python自动翻译实现方法
2016/05/28 Python
import的本质解析
2017/10/30 Python
python机器学习之随机森林(七)
2018/03/26 Python
Python字典创建 遍历 添加等实用基础操作技巧
2018/09/13 Python
Python编程中flask的简介与简单使用
2018/12/28 Python
使用python serial 获取所有的串口名称的实例
2019/07/02 Python
python读写配置文件操作示例
2019/07/03 Python
3种适用于Python的疯狂秘密武器及原因解析
2020/04/29 Python
Python基于爬虫实现全网搜索并下载音乐
2021/02/14 Python
《列夫托尔斯泰》教学反思
2014/02/10 职场文书
北京申奥口号
2014/06/19 职场文书
认错检讨书
2014/10/02 职场文书
2021年最新用于图像处理的Python库总结
2021/06/15 Python
教你怎么用Python实现GIF动图的提取及合成
2021/06/15 Python