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 相关文章推荐
取得父标签
Nov 14 Javascript
js实现屏蔽默认快捷键调用自定义事件示例
Jun 18 Javascript
解析JavaScript中instanceof对于不同的构造器或许都返回true
Dec 03 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
Dec 08 Javascript
noty ? jQuery通知插件全面解析
May 18 Javascript
JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)
Aug 11 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
Nov 24 Javascript
Bootstrap CSS布局之列表
Dec 15 Javascript
jquery拼接ajax 的json和字符串拼接的方法
Mar 11 Javascript
Webpack devServer中的 proxy 实现跨域的解决
Jun 15 Javascript
layui的table中显示图片方法
Aug 17 Javascript
vue移动端项目缓存问题实践记录
Oct 29 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函数
2006/12/06 PHP
javascript some()函数用法详解
2014/11/13 PHP
php中JSON的使用与转换
2015/01/14 PHP
关于图片的预加载过程中隐藏未知的
2012/12/19 Javascript
JQuery弹出炫丽对话框的同时让背景变灰色
2014/05/22 Javascript
让checkbox不选中即将选中的checkbox不选中
2014/07/11 Javascript
基于jquery实现轮播焦点图插件
2016/03/31 Javascript
jQuery的Each比JS原生for循环性能慢很多的原因
2016/07/05 Javascript
关于javascript原型的修改与重写(覆盖)差别详解
2016/08/31 Javascript
慕课网题目之js实现抽奖系统功能
2017/09/19 Javascript
AngularJs分页插件使用详解
2018/06/30 Javascript
详解如何使用nvm管理Node.js多版本
2019/05/06 Javascript
JavaScript canvas绘制渐变颜色的矩形
2020/02/18 Javascript
vue使用nprogress加载路由进度条的方法
2020/06/04 Javascript
JavaScript中作用域链的概念及用途讲解
2020/08/06 Javascript
详解如何在vue+element-ui的项目中封装dialog组件
2020/12/11 Vue.js
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
利用Python绘制MySQL数据图实现数据可视化
2015/03/30 Python
Python栈类实例分析
2015/06/15 Python
Django中的“惰性翻译”方法的相关使用
2015/07/27 Python
Python实现备份MySQL数据库的方法示例
2018/01/11 Python
详解python里的命名规范
2018/07/16 Python
python中协程实现TCP连接的实例分析
2018/10/14 Python
Django如何自定义model创建数据库索引的顺序
2019/06/20 Python
基于python实现文件加密功能
2020/01/06 Python
基于python实现模拟数据结构模型
2020/06/12 Python
美国专业级皮肤病和spa品质护肤品的高级零售网站:SkinCareRx
2017/02/06 全球购物
如果Session Bean得Remove方法一直都不被调用会怎么样
2012/07/14 面试题
商务英语专业毕业生自荐信
2013/11/05 职场文书
简历自我评价怎么写好呢?
2014/01/04 职场文书
给老师的道歉信
2014/01/11 职场文书
银行优秀员工事迹材料
2014/05/29 职场文书
国际贸易专业求职信
2014/06/04 职场文书
民主生活会对照检查材料(统计局)
2014/09/21 职场文书
2014年党委工作总结
2014/11/22 职场文书
dubbo服务整合zipkin详解
2021/07/26 Java/Android