JS中this上下文对象使用方式


Posted in Javascript onOctober 09, 2016

JavaScript 有一套完全不同于其它语言的对 this 的处理机制。 在五种不同的情况下 ,this 指向的各不相同。

有句话说得很在理 -- 谁调用它,this就指向谁

一、全局范围内

在全局范围内使用this ,它将指向全局对象(浏览器中为 window)

var name = 'name1';
console.log(name);

this.name = 'name2';
console.log(name);
console.log(this.name);

window.name = 'name3';
console.log(name);
console.log(this.name);
console.log(window.name);

JS中this上下文对象使用方式

二、函数调用

直接调用一个函数,this 默认会指向全局 (浏览器端为window)

var name = 'name1';
function sayName(){
 console.log(name);
 console.log(this);
}

sayName();
window.sayName();

可以看到

JS中this上下文对象使用方式

还有几个常见的情况,根据谁调用方法就指向谁的原则,this的指向要细看

// 全局 name
var name = 'name1';

var obj = {
 name: 'name2',
 sayName: function(){
    // 调用它的时候 this指向全局
  return function(){
   console.log(this.name);
  };
 },
 changeName: function(){
    // 调用它的时候 this指向全局
  setTimeout(function(){
   this.name = 'name3';
  },0);
 }
};

obj.sayName()();
obj.changeName();
setTimeout(function(){
 console.log(name);
 console.log(obj.name);
},0);

JS中this上下文对象使用方式

像这些类似匿名的函数,默认都是被全局(浏览器下的window)对象调用,要正确地让obj调用,就要指代好

可以用that保持this再进行下一步,或者匿名函数传值,或者使用call/apply/bind改变context等

var name = 'name1';

var obj = {
 name: 'name2',
 sayName: function(){
  var that = this;
  return function(){
   console.log(that.name);
  };
 },
 changeName: function(){
  var that = this;
  setTimeout(function(){
   that.name = 'name3';
  },0);
 }
};

obj.sayName()(); // name2
obj.changeName();
setTimeout(function(){
 console.log(name); // name1
 console.log(obj.name); // name3
},0);

三、作为对象方法的调用

其实就类似上头提到的 obj.sayName()  obj.name 等

这时this会指向这个obj 

四、call/apply/bind 的调用

当使用 Function.prototype 上的 call 或者 apply ,bind 方法时,函数内的 this将会被 显式设置为函数调用的第一个参数。

具体使用方法

我们可以稍微修改一下上头的代码,就可以看到this指向的改变

var name = 'name1';

var obj = {
 name: 'name2',
 sayName: function(){
  // 返回一个默认全局的函数
  return function(){
   console.log(this.name);
  };
 },
 changeName: function(){
  // 返回一个默认全局的函数
  setTimeout(function(){
   this.name = 'name3';
  // 然后将该函数绑定给this(当前obj对象)
  }.bind(this),0);
 }
};

// obj.sayName()这个函数,让obj来调用
obj.sayName().call(obj);
// 让this(也就是全局对象)来调用
obj.sayName().apply(this);

obj.changeName();
setTimeout(function(){
 // 输出更改之后,全局name的值
 console.log(name);
 // 输出更改之后,obj对象中 name的值
 console.log(obj.name);
},0);

JS中this上下文对象使用方式

五、作为构造函数调用

比如 new Foo();

先来看个简单的例子:

var name = 'name1';
function Foo(){
 // 赋值this(当前对象)的name属性值
 this.name = 'name2';
}

// new 构造函数产生一个实例
var foo = new Foo();

console.log(name);
console.log(foo.name);

// 直接调用该函数
Foo();
console.log(name);

JS中this上下文对象使用方式

可以看到,如果函数倾向于和 new 关键词一块使用,则我们称这个函数为构造函数,当new 了之后,this则指向这个心创建的对象(这个new 的过程其实也涉及到了继承机制)。

若直接调用这个函数,this就默认执行全局对象了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jQuery的公告无限循环滚动实现代码
May 11 Javascript
JS或jQuery获取ASP.NET服务器控件ID的方法
Jun 08 Javascript
bootstrap datetimepicker实现秒钟选择下拉框
Jan 05 Javascript
Angular的$http的ajax的请求操作(推荐)
Jan 10 Javascript
写jQuery插件时的注意点
Feb 20 Javascript
vue.js开发环境搭建教程
May 04 Javascript
vue组件父子间通信之综合练习(聊天室)
Nov 07 Javascript
vue-cli项目使用mock数据的方法(借助express)
Apr 15 Javascript
小程序实现日历左右滑动效果
Oct 21 Javascript
基于ts的动态接口数据配置的详解
Dec 18 Javascript
JavaScript 判断数据类型的4种方法
Sep 11 Javascript
微信小程序onShareTimeline()实现分享朋友圈
Jan 07 Javascript
JS判断来路是否是百度等搜索索引进行弹窗或自动跳转的实现代码
Oct 09 #Javascript
jQuery Ajax传值到Servlet出现乱码问题的解决方法
Oct 09 #Javascript
BootStrap中Table分页插件使用详解
Oct 09 #Javascript
微信小程序 for 循环详解
Oct 09 #Javascript
微信小程序 条件渲染详解
Oct 09 #Javascript
手机浏览器 后退按钮强制刷新页面方法总结
Oct 09 #Javascript
最实用的jQuery分页插件
Oct 09 #Javascript
You might like
php批量缩放图片的代码[ini参数控制]
2011/02/11 PHP
解析PHP对现有搜索引擎的调用
2013/06/25 PHP
php删除一个路径下的所有文件夹和文件的方法
2018/02/07 PHP
高性能WEB开发 flush让页面分块,逐步呈现 flush让页面分块,逐步呈现
2010/06/19 Javascript
JQuery学习笔记 nt-child的使用
2011/01/17 Javascript
jquery 卷帘效果实现代码(不同方向)
2013/02/05 Javascript
页面按钮禁用与解除禁用的方法
2014/02/19 Javascript
JS实现闪动的title消息提醒效果
2014/06/20 Javascript
js监控IE火狐浏览器关闭、刷新、回退、前进事件
2014/07/23 Javascript
jquery简单实现网页层的展开与收缩效果
2015/08/07 Javascript
基于JavaScript实现百度搜索框效果
2020/06/28 Javascript
JavaScript代码判断输入的字符串是否含有特殊字符和表情代码实例
2017/08/17 Javascript
vue实现点击展开点击收起效果
2018/04/27 Javascript
浅析Vue项目中使用keep-Alive步骤
2018/07/27 Javascript
VUE预渲染及遇到的坑
2018/09/03 Javascript
Nodejs对postgresql基本操作的封装方法
2019/02/20 NodeJs
详解在Javascript中进行面向切面编程
2019/04/28 Javascript
npm的lock机制解析
2019/06/20 Javascript
jQuery实现的记住帐号密码功能完整示例
2019/08/03 jQuery
JS代码优化的8点建议
2020/02/04 Javascript
仅用500行Python代码实现一个英文解析器的教程
2015/04/02 Python
详解python发送各类邮件的主要方法
2016/12/22 Python
Python使用Phantomjs截屏网页的方法
2018/05/17 Python
python按键按住不放持续响应的实例代码
2019/07/17 Python
python tkinter之 复选、文本、下拉的实现
2020/03/04 Python
python传到前端的数据,双引号被转义的问题
2020/04/03 Python
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
what is the difference between ext2 and ext3
2015/08/25 面试题
冰淇淋店的创业计划书
2014/02/07 职场文书
2014年机关植树节活动方案
2014/02/27 职场文书
自我鉴定书
2014/03/24 职场文书
请假条的格式
2014/04/11 职场文书
模具设计与制造专业求职信
2014/07/19 职场文书
安全员岗位职责
2015/02/10 职场文书
小学教师见习总结
2015/06/23 职场文书
OpenCV图像变换之傅里叶变换的一些应用
2021/07/26 Python