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 相关文章推荐
始终在屏幕中间显示Div的代码(css+js)
Mar 10 Javascript
获取body标签的两种方法
Oct 13 Javascript
JS获取整个页面文档的实现代码
Dec 15 Javascript
jQuery实现点击标题输入详细信息
Apr 16 Javascript
获取非最后一列td值并将title设为该值的方法
Oct 30 Javascript
JavaScript获得当前网页来源页面(即上一页)的方法
Apr 03 Javascript
ionic 3.0+ 项目搭建运行环境的教程
Aug 09 Javascript
javascript和php使用ajax通信传递JSON的实例
Aug 21 Javascript
微信小程序MUI导航栏透明渐变功能示例(通过改变opacity实现)
Jan 24 Javascript
基于layui实现高级搜索(筛选)功能
Jul 26 Javascript
小程序实现上下切换位置
Nov 16 Javascript
vue祖孙组件之间的数据传递案例
Dec 07 Vue.js
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
MVC模式的PHP实现
2006/10/09 PHP
php获取地址栏信息的代码
2008/10/08 PHP
精通php的十大要点(上)
2009/02/04 PHP
php实现简单洗牌算法
2013/06/18 PHP
PHP通过文件路径获取文件名的实例代码
2018/10/14 PHP
PHP SESSION机制的理解与实例
2019/03/22 PHP
中止javascript执行的方法
2014/02/14 Javascript
全面兼容的javascript时间格式化函数(比较实用)
2014/05/14 Javascript
jQuery学习笔记之jQuery.extend(),jQuery.fn.extend()分析
2014/06/09 Javascript
javascript学习总结之js使用技巧
2015/09/02 Javascript
jQuery基础知识点总结(必看)
2016/05/31 Javascript
ES6新特性之解构、参数、模块和记号用法示例
2017/04/01 Javascript
使用Xcache缓存器加速PHP网站的配置方法
2017/04/22 Javascript
Vue原理剖析 实现双向绑定MVVM
2017/05/03 Javascript
Javascript创建类和对象详解
2017/05/31 Javascript
vue2.0设置proxyTable使用axios进行跨域请求的方法
2017/10/19 Javascript
详解JQuery基础动画操作
2019/04/12 jQuery
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
Python unittest单元测试框架总结
2018/09/08 Python
深入解析神经网络从原理到实现
2019/07/26 Python
Python matplotlib生成图片背景透明的示例代码
2019/08/30 Python
Django实现文件上传下载功能
2019/10/06 Python
使用python图形模块turtle库绘制樱花、玫瑰、圣诞树代码实例
2020/03/16 Python
Keras load_model 导入错误的解决方式
2020/06/09 Python
如何基于Python Matplotlib实现网格动画
2020/07/20 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
2020/11/02 Python
跑步爱好者一站式服务网站:Jack Rabbit
2016/09/01 全球购物
Dune London官网:英国著名奢华鞋履品牌
2017/11/30 全球购物
面临毕业的毕业生自荐书范文
2014/02/05 职场文书
优秀家长事迹材料
2014/05/17 职场文书
毕业实习自我鉴定范文2014
2014/09/26 职场文书
个人廉洁自律总结
2015/03/06 职场文书
2015社区健康教育工作总结
2015/05/20 职场文书
初婚未育证明样本
2015/06/18 职场文书
基于CSS3画一个iPhone
2021/04/21 HTML / CSS
Python基础详解之描述符
2021/04/28 Python