在绝大多数情况下,函数的调用方式决定了this的值

全局环境

无论是否在严格模式下,在全局执行环境中,this都指向全局对象·

在全局作用域中调用一个函数时,this总是指向Global对象(在浏览器中指向window)

函数(运行内)环境

在函数内部,this的值取决于函数被调用的方式

1.简单调用

非严格模式
function f1() {console.log(this);
}
// 在浏览器环境
f1();//window// 在Node环境
f1();//global

严格模式

在严格模式下,如果this没有被执行环境(execution context)或者称为上下文,this会保持它进入执行环境时的值,所以下面this会被默认为undefined

function f2() {'use strict';console.log(this);
}
f2(); //undefined

使用call()或者apply()方法,改变this的指向

// 如果想把this的值从一个环境传到另一个,就可以调用call()或者apply()方法
var o = {a: 'Customs'
};
var o1 = {a: 'Customs1'
};
var o2 = {a: 'Customs2'
};
var a = 'Global';
function whatThis(arg) {console.log(this.a);
}whatThis(); //Global
whatThis.call(o); //Customs
whatThis.apply(o); //Customs
whatThis.call(o1); //Customs1
whatThis.apply(o1); //Customs1
whatThis.call(o2); //Customs2
whatThis.apply(o2); //Customs2

强制指向,即改变函数的调用对象
两者有何异同?
apply(thisObj,[argsArray])
call(thisObj,arg1,arg2,arg3)
call()与apply()方法类似,区别就是接受的参数形式不一样
apply()接受的是数组;call()接受的是以逗号分隔的参数
使用 call 和 apply 函数的时候要注意,如果传递给 this 的值不是一个对象,JavaScript 会尝试使用内部 ToObject 操作将其转换为对象。
因此,如果传递的值是一个原始值比如 7 或 'foo',那么就会使用相关构造函数将它转换为对象,所以原始值 7 会被转换为对象,像 new Number(7) 这样,而字符串 'foo' 转化成 new String('foo') 这样,
function bar() {console.log(Object.prototype.toString.call(this));
}//原始值 7 被隐式转换为对象
bar.call(7); // [object Number]

2.作为对象的方法调用

当函数作为对象的方法调用,他们的this是调用该函数的对象

var x4 = 44;
function f4() {console.log(this.x4); //{x:55,say:f4} this指向o4
}
var o4 = {};
o4.x4 = 55;
o4.say = f4;
o4.say(); // 55

var x5 = 56;
var o5 = {x5: 66,f5: function() {    console.log(this)  // {x5:66,f5:f} this指向o5

// console.log(this.x5);//66
    return this.x5;}
};console.log(o5.f5()); //66

原型链中的this

对于原型链上某处定义的方法,同样也适用, 如果该方法存在于对象的原型链上,那么this的指向的是调用该方法的对象

var oo = {f: function() {return this.a + this.b;}
};var p = Object.create(oo);
p.a = 1;
p.b = 2;
console.log(p.f()); // 3
// 解析:对象p没有自己的f属性,该属性继承自原型,
// 对于f的查找过程中,最终在对象oo中找到f属性,查找的过程是p.f的引用开始的,所以this指向p
// 也就是说,因为f是作为p的方法调用的,所以this指向p

getter和setter中的this
当一个函数在一个setter或者getter中被调用
用作getter或者setter的函数都会把this绑定到设置或者获取属性的对象

function sum() {console.log(this); //{a: 1,average: 2,b: 2, c: 3,sum: 6}return this.a + this.b + this.c;
}
var oo1 = {a: 1,b: 2,c: 3,get average() {console.log(this);//{a: 1,average: 2,b: 2, c: 3,sum: 6}return (this.a + this.b + this.c) / 3;}
};Object.defineProperty(oo1, 'sum', {get: sum,enumerable: true,configurable: true
});console.log(oo1.average, oo1.sum); // 2,6

3.作为构造函数

当一个函数作为构造函数时(使用new关键字),他的this指向用构造函数创建的对象

function Test() {this.x = 3;
}
var obj1 = new Test();
console.log(obj1.x); // 3
// 解析:this指向Test的实例,即obj1
obj1.x = 5;
console.log(obj1.x); // 5

4.bind()方法

ES5引入Function.prototype.bind()

调用 f.bind()方法会创建一个与 f具有相同的函数体和作用域的函数

但是在这个函数中,this将永久性的被绑定到了bind的第一个参数,无论函数是怎么样调用的

var a3 = 'Global';
function f3() {console.log(this.a3); //zhangsanreturn this.a3;
}var g = f3.bind({ a3: 'zhangsan' });
console.log(g()); // zhangsanvar h = g.bind({ a3: 'haha' }); // bind只生效一次,再次修改也不会生效
console.log(h()); // zhangsanvar o3 = {a3: 37,f3: f3,g: g,h: h
};
console.log(o3.f3(), o3.g(), o3.h()); // 37,"zhangsan","zhangsan"

5.作为一个DOM时间处理函数

当函数被用作事件处理函数时,它的this指向触发事件的元素

6.作为一个内联事件处理函数

当代码被内联on-event 处理函数调用时,它的this指向监听器所在的DOM元素

参考:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this
http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html

转载于:https://www.cnblogs.com/shengnan-2017/p/10407013.html

面向对象之---this的用法相关推荐

  1. php final这个关键词代表什么,php面向对象之final关键字用法及实例

    这节课我们来说一下关于final关键字的概念和用法. 什么是final关键字? final中文翻译为"最终的","最后的".在声明一个类之前用final关键词修 ...

  2. php 对象的操作符,php面向对象之操作符'::'的用法简述

    什么是操作符"::"? 操作符"::"相比伪变量$this只能在类的内部使用来说更为强大.操作符"::"可以在没有任何声明任何实例的情况下访 ...

  3. php面向对象全攻略 (十四),php面向对象全攻略 (十四) php5接口技术

    20.PHP5接口技术 PHP与大多数面向对象编程语言一样,不支持多重继承.也就是说每个类只能继承一个父 类.为了解决这个问题,PHP引入了接口,接口的思想是指定了一个实现了该接口的类必须 实现的一系 ...

  4. PHP中__get()和__set()的用法实例详

    刚刚看到一个对我有用的文章,我就把它摘抄下来了.                                                                        php面 ...

  5. 编程体系结构(06):Java面向对象

    本文源码:GitHub·点这里 || GitEE·点这里 一.基础概念 1.面向对象概念 面向对象编程的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙一 ...

  6. 面向对象 -- 类与对象(B版)

    课程笔记Day07 面向对象基础 方法基础用法 第一章 面向对象基础 第01节 思想概述 什么是面向对象? 面向过程:所有的事情,都是自己做.(亲力亲为) 面向对象:找人帮你做事情,请的人叫做对象,对 ...

  7. css和js实现3d图片,JavaScript_纯JS实现旋转图片3D展示效果,CSS:style type=text/cssgt - phpStudy...

    纯JS实现旋转图片3D展示效果 CSS: #show{position:relative;margin:20px auto;width:800px;} .item{position:absolute; ...

  8. linux获取命令的返回值,怎样获取shell函数的返回值及shell命令的返回值?

    Jenkins + svn + maven 构建持续集成环境搭建 Jenkins简介 Jenkins是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. Jenkins是基于 ...

  9. 中文汉字转换拼音PHP类

    1 <?php 2 /** 3 * 中文汉字转换拼音类 4 * 功能支持 5 * 1.支持中文转换全拼 6 * 2.支持中文转换简拼(首字母) 7 * 3.支持转换的字符串返回格式设置(字符中间 ...

  10. 3年Java后端开发面试题总结

    3年Java开发经验面试题总结 毕业转行做开发3年以来, 学到了很多, 加上自己的兴趣爱好, 个人认为已经成为了一个合格的程序员. 与刚开始找工作面试相同的是都会问一些相同的问题, 不同的是现在面试官 ...

最新文章

  1. JAVA 和 GO 真香!谁用谁知道!
  2. SpringMVC获取请求参数-POJO类型参数
  3. SAP系统财务模块的集团公司处理模式
  4. ffmpeg 配置与编译
  5. leetcode406. 根据身高重建队列
  6. python 波动率_旧文:历史波动率的计算 (Python)
  7. 挂载镜像SD卡的FAT32文件系统分区到Linux中
  8. python中模块文件的扩展名不一定是py_python模块和python包有什么区别?
  9. 微波网络中插入相移插入衰减和输入驻波比
  10. [R语言] R语言快速入门教程
  11. 使用curl清理Elasticsearch数据方法
  12. ios10--拳皇动画
  13. 【已解决】系统找不到文件 C:\ProgramData\Oracle\Java\javapath\java.exe。
  14. Windows10下美化字体,达到类似mac的效果
  15. OA项目实战学习(3)——实现岗位管理增删改查
  16. [java编程题]买苹果
  17. PHP全站pjax影响收录,zblogPHP增加pjax功能,大写的一个“帅”字 - 胡言乱语
  18. String转字节数组
  19. CSS 字符间距letter-spacing属性
  20. 明远智睿MY-IMX6 底板设计指南

热门文章

  1. 软件测试 因果+决策案例--中国象棋中走马
  2. !! A股历史平均市盈率走势图
  3. php网站挂马,转 :php 网站挂马检查
  4. zz 主要分类方法介绍
  5. python太阳花画法_Python——教你画朵太阳花
  6. 从40,000到320,000美元,揭秘大型科技公司薪酬细节
  7. 深圳保障性住房【公租房、安居房、人才房】简单说明
  8. Win系统 - 开启 WIN10 隐藏的卓越性能模式
  9. python保存快捷键是什么_python中的快捷键
  10. 全球及中国超声波智能燃气表行业研究及十四五规划分析报告