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 相关文章推荐
Lazy Load 延迟加载图片的 jQuery 插件
Feb 06 Javascript
js 未结束的字符串常量错误解决方法
Jun 13 Javascript
js字符串转换成xml对象并使用技巧解读
Apr 18 Javascript
ListBox实现上移,下移,左移,右移的简单实例
Feb 13 Javascript
JavaScript实现在数组中查找不同顺序排列的字符串
Sep 26 Javascript
JavaScript自定义分页样式
Jan 17 Javascript
JS验证不重复验证码
Feb 10 Javascript
基于vuejs实现一个todolist项目
Apr 11 Javascript
Vue如何实现组件的源码解析
Jun 08 Javascript
详解JavaScript添加给定的标签选项
Sep 17 Javascript
vue微信分享到朋友圈 vue微信发送给好友
Nov 28 Javascript
Vue中JS动画与Velocity.js的结合使用
Feb 13 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
咖啡豆要不要放冰箱的原因
2021/03/04 冲泡冲煮
PHP读MYSQL中文乱码的解决方法
2006/12/17 PHP
php数组函数序列之array_pop() - 删除数组中的最后一个元素
2011/11/07 PHP
php实现面包屑导航例子分享
2015/12/19 PHP
PHP结合Jquery和ajax实现瀑布流特效
2016/01/07 PHP
详细解读php的命名空间(一)
2018/02/21 PHP
Laravel Reponse响应客户端示例详解
2020/09/03 PHP
无语,javascript居然支持中文(unicode)编程!
2007/04/12 Javascript
javascript 面向对象编程基础:封装
2009/08/21 Javascript
浅谈javascript 面向对象编程
2009/10/28 Javascript
JavaScript DOM学习第八章 表单错误提示
2010/02/19 Javascript
基于jquery 的一个progressbar widge
2010/10/29 Javascript
javascript中String对象的slice()方法分析
2014/12/20 Javascript
jQuery实现的Div窗口震动效果实例
2015/08/07 Javascript
D3.js中data(), enter() 和 exit()的问题详解
2015/08/17 Javascript
TypeScript Type Innference(类型判断)
2016/03/10 Javascript
第一次接触神奇的Bootstrap导航条
2016/08/09 Javascript
JS多文件上传的实例代码
2017/01/11 Javascript
对vue中v-on绑定自定事件的实例讲解
2018/09/06 Javascript
使用puppeteer爬取网站并抓出404无效链接
2018/12/20 Javascript
vue-router beforeEach跳转路由验证用户登录状态
2018/12/26 Javascript
通过实例解析js可枚举属性与不可枚举属性
2020/12/02 Javascript
python抓取最新博客内容并生成Rss
2015/05/17 Python
python素数筛选法浅析
2018/03/19 Python
python合并已经存在的sheet数据到新sheet的方法
2018/12/11 Python
在pycharm下设置自己的个性模版方法
2019/07/15 Python
Python算法中的时间复杂度问题
2019/11/19 Python
Python代码需要缩进吗
2020/07/01 Python
Staples美国官方网站:办公用品一站式采购
2016/07/28 全球购物
高品质和独特的产品世界:Creations and Collections
2018/01/07 全球购物
出纳员的岗位职责
2014/02/22 职场文书
跑吧孩子观后感
2015/06/10 职场文书
pytorch--之halfTensor的使用详解
2021/05/24 Python
详细了解MVC+proxy
2021/07/09 Java/Android
关于Python中*args和**kwargs的深入理解
2021/08/07 Python
idea以任意顺序debug多线程程序的具体用法
2021/08/30 Java/Android