js this详解
This的定义:
它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象,
这说明this关键字只与函数的执行环境有关,而与声明环境没有关系。下面通过例子来讲解。
例子1:
function a(){
var user = "哈哈哈";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
既然this的最终指向的是那个调用它的对象,a()的执行就相当于window.a(),所以this指向window.
例子2:
var o = {
user:"哈哈哈",
fn:function(){
console.log(this.user); //哈哈哈
}
}
o.fn();
这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o,这里再次强调一点,this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁。
例子3:
var o = {
a:’哈哈哈’,
b:{
a:’呵呵呵’,
fn:function(){
console.log(this.a); //呵呵呵
}
}
}
o.b.fn();
如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象(不管有没有this要的东西,没有就输出undefined)。
例子4:
var o = {
a:’哈哈哈’,
b:{
a:’呵呵呵’,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子4中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window,这和例子3是不一样的,例子3是直接执行了fn。
例子5:
var id = 'windowId';
document.getElementById('myDiv').onclick = function() {
console.log(this.id); //输出myDiv
function fn(){
console.log(this.id); //输出windowId
};
fn(); //普通函数调用
};
这里补充下:不管函数处于什么样的执行环境,只要是当普通函数调用,this就指向windows.
例子6:
var a=function(){
console.log(this)//window
}
var o={
name:'小白菜',
b:function(fn){
console.log(this);//{name:'小白菜',b:f(fn)}
fn()
a();
}
}
o.b(function(){
console.log(this)//window
})
这个例子是我之前的面试题目,也是因为它而让我想写这篇文章。我想大家看到这里大概明白b函数里面的this,就是指向它的执行环境o。迷糊的估计是fn()和a()的输出。其实简单理解就像例5我所说的,不管处于什么样的环境下,只要当普通函数调用就指向window。硬要说个理由,就像开头所说的:this的最终指向的是那个调用它的对象。本例子fn()=window.fn()。
补充1:
、
function fn()
{
this.name = '哈哈哈';
return {};
}
var a = new fn();
console.log(a.name ); //undefined
、
function fn()
{
this.name = '哈哈哈';
return function(){};
}
var a = new fn();
console.log(a.name ); //undefined
、
function fn()
{
this.name = '哈哈哈';
return ;
}
var a = new fn();
console.log(a.name ); //哈哈哈
、
function fn()
{
this.name = '哈哈哈';
return undefined;
}
var a = new fn();
console.log(a.name ); //哈哈哈
、
function fn()
{
this.name = '哈哈哈';
return null;
}var a = new fn;
console.log(a.name ); //哈哈哈
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。
补充2:
this一般指向的是当前被调用者,但也可以通过其它方式来改变它的指向,为什么要改变向上下文呢?主要是为了实现一种情况,当一个对象没有某个方法的时候,而且另外一个对象却有这个方法,这个时候就可以通过改变上下文来使用自己没有的方法了。
如下面的例子:
var obj1 = {
name: ''
}
var obj2 = {
name: ''
}
window.name = 'window';
var getName= function(a,b) {
alert(this.name);
alert(a);
alert(b);
}
getName();//window,undefined,undefined;
getName.call(obj1,'a','b');//111,a,b
getName.apply(obj2,['a','b']);//222,a,b
obj1没有showName()方法,obj2有,这个时候可以这个样子使用,var temp=obj1.prototype.call(obj2);这样就可以用obj2的方法了。
那什么时候用call什么时候用apply?
当参数个数是固定不变的时候可以用call,当参数个数不确定可以用apply,把要传递的参数push到一个数组里面然后传递给函数,不清楚call和apply可以猛戳百度。
如想了解this的作用可阅读《this的作用》这篇文章。
js this详解的更多相关文章
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- Node.js npm 详解
一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...
- Vue.js项目详解
还是以Blog项目来讲解,最近我本人利用闲暇时间,以博客作为参考学习一些新的技术并尝试之前没有尝试过的思路来玩玩. 技术看似枯燥,但是带有一个目的来学,你会发现还是蛮有趣的. 主要实践的就是前后端分离 ...
- JS 面向对象详解
面向对象详解1 OO1.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- 开胃小菜——impress.js代码详解
README 友情提醒,下面有大量代码,由于网页上代码显示都是同一个颜色,所以推荐大家复制到自己的代码编辑器中看. 今天闲来无事,研究了一番impress.js的源码.由于之前研究过jQuery,看i ...
- jquery图片切换插件jquery.cycle.js参数详解
转自:国人的力量 blog.163.com/xz551@126/blog/static/821257972012101541835491/ 自从使用了jquery.cycle.js,我觉得再也不用自己 ...
- 值得收藏的js原型详解
从虚无到Object 起初,地是空虚混沌,渊面黑暗:这时候一切还是null 神说,要有原型,于是就有了prototype 原型从凭空产生,于是需要一个指向于null的特征,人们把这种特征叫做隐式原型, ...
- 第三天:JS事件详解-事件流
学习来源: F:\新建文件夹 (2)\HTML5开发\HTML5开发\04.JavaScript基础\6.JavaScript事件详解 学习内容: 1)基础概念 2)举例说明: 代码如上,如果用事件 ...
- 第二十二课:js事件原理以及addEvent.js的详解
再看这篇博客之前,希望你已经对js高级程序编程一书中的事件模块进行了详读,不然我只能呵呵了. document.createEventObject,在IE下创建事件对象event. elem.fire ...
- require('./expample.js).default详解
最近总碰到类似于 var a = require('./expample.js).default 这样的代码,感觉很奇葩,总结一波. 为什么会出现这个问题? import 是静态编译的,而 requi ...
随机推荐
- jodatime 计算时间差_统计程序运行耗时
https://blog.csdn.net/De_Moivre/article/details/79775661 记录开始执行的时间 DateTime startDateTime=new DateTi ...
- day18 11.复习
其实以前写的每条SQL语句都是有事务的,因为它默认的事务是autocommit=on(自动事务).mysql的autocommit是on,oracle的autocommit是off.
- Struts_改写客户列表练习
1.CustomerAction修改放入ActionContext 2.list.jsp使用struts标签库
- ASP.NET自定义控件组件开发 第一章 第一章:从一个简单的控件谈起
第一章:从一个简单的控件谈起 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第三 ...
- 为Array对象添加一个去除重复项的方法
输入例子 [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN].uniq() 输出例子 [false, true, unde ...
- oracle-ASM存储器
自动存储管理 Oracle 10g引进的一种新型存储机制.它依靠oracle来维护企业的数据库存储器,被设计用来解除磁盘和存储器管理的负担,可以使用ASM来定义用于文件管理的磁盘组. 磁盘组类似于某些 ...
- 来自 Spring Cloud 官方的消息,Spring Cloud Alibaba 即将毕业
2019 年 7 月 24 日晚,Spring Cloud 官方发布公告: 仓库迁移是官方决定 Spring Cloud Alibaba 即将毕业 根据官方最新的发版规则,我们会把孵化器中的 Spri ...
- 视觉暂留-Info:这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝!
ylbtech-视觉暂留-Info:这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝! 1.返回顶部 1. 这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝! 原创|发布:2018-05-28 19: ...
- 2019-7-22-WPF-如何判断两个-LinearGradientBrush-相等
title author date CreateTime categories WPF 如何判断两个 LinearGradientBrush 相等 lindexi 2019-07-22 21:26:2 ...
- 2018-11-30-WPF-解决-ListView-的滚动条不显示
title author date CreateTime categories WPF 解决 ListView 的滚动条不显示 lindexi 2018-11-30 19:24:57 +0800 20 ...