JS基础:this的指向以及call、apply的作用
this 的指向
在具体的实际应用中,this 的指向无法在函数定义时确定,而是在函数执行的时候才确定的,根据执行时的环境大致可以分为以下3种:
1、当函数作为普通函数调用时,this 指向全局对象
2、当函数作为对象的方法调用时,this 指向该对象
3、当函数作为构造器调用时,this 指向新创建的对象
示例一:
window.name = 'myname';
function getName() {
console.log(this.name);
}
getName(); //输出myname
示例二:
var boy = {
name: 'Bob',
getName: function() {
console.log(this.name);
}
}
boy.getName(); //输出Bob
示例三:
function Boy(name) {
this.name = name;
}
var boy1 = new Boy('Bob');
console.log(boy1.name); //输出Bob
对于示例三,还有一种特殊情况,就是当构造函数通过 "return" 返回的是一个对象的时候,此次运算的最终结果返回的就是这个对象,而不是新创建的对象,因此 this 在这种情况下并没有什么用。
示例四:
function Boy(name) {
this.name = name;
return { //返回一个对象
name: 'Jack'
}
}
var boy1 = new Boy('Bob');
console.log(boy1.name); //输出Jack
示例五:
function Boy(name) {
this.name = name;
return 1; //返回非对象
}
var boy1 = new Boy('Bob');
console.log(boy1.name); //输出Bob
apply 和 call 的作用
apply 接受两个参数,第一个参数指定了函数体内 this 的指向,第二个参数是一个数组或类数组,用于传递被调用函数的参数列表。
示例一:
function getInfo() {
console.log(this.name+' like '+arguments[0]+' and '+arguments[1]);
}
var boy1 = {
name: 'Bob',
age: 12
}
getInfo.apply(boy1,['sing','swimming']); //输出Bob like sing and swimming
call 传入参数的数量是不固定的,跟 apply 相同的是,第一个参数也是用于指定函数体内 this 的指向,从第二个参数开始往后,每个参数被依次传入被调用函数。
示例二:
function getInfo() {
console.log(this.name+' like '+arguments[0]+' and '+arguments[1]);
}
var boy1 = {
name: 'Bob',
age: 12
}
getInfo.call(boy1,'sing','shopping'); //输出Bob like sing and shopping
此外,大部分高级浏览器还实现了 bind 方法,bind 方法会返回一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入的第一个参数作为 this,传入的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
示例三:
var boy1 = {
name: 'Bob',
age: 12
}
var getInfo = function() {
console.log(this.name + ' like ' + arguments[0] + ' and ' + arguments[1]);
}.bind(boy1,'sing');
getInfo('shopping'); //输出Bob like sing and shopping
示例四:模拟浏览器的 bind 方法
Function.prototype.bind = function(obj){
var self = this;
return function(){
return self.apply(obj,arguments);
}
};
var boy1 = {
name: 'Bob',
age: 12
};
var func = function(){
console.log(this.name+' like '+arguments[0]+' and '+arguments[1]);
}.bind(boy1);
func('sing','shopping');
丢失的 this
在某些情况下会丢失 this 的指向,此时,我们就需要借助 call、apply 和 bind 来改变 this 的指向问题。
示例一:当 "getName" 方法作为 "boy" 对象的属性调用时,this 指向 "boy" 对象,当另外一个变量引用 "getName" 方法时,因为它是作为普通函数调用,所以 this 指向全局对象window
var boy = {
name: 'Bob',
getName: function() {
console.log(this.name);
}
}
boy.getName(); //输出Bob
var getBoyName = boy.getName;
getBoyName(); //输出undefind
示例二:即使在函数内部定义的函数,如果它作为普通对象调用,this 同样指向 window 对象
var boy1 = {
name: 'Bob',
age: 12,
getInfo: function() {
console.log(this.name);
function getAge() {
console.log(this.age);
}
getAge();
}
}
boy1.getInfo(); //Bob
//undefind
JS基础:this的指向以及call、apply的作用的更多相关文章
- js基础梳理-关于this常见指向问题的分析
首先,依然回顾<js基础梳理-究竟什么是执行上下文栈(执行栈),执行上下文(可执行代码)?>中的 3.执行上下文的生命周期 3.1 创建阶段 生成变量对象(Variable object, ...
- js基础篇——call/apply、arguments、undefined/null
a.call和apply方法详解 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象 ...
- js中改变this指向的call、apply、bind 方法使用
前言: 由于js 中this的指向受函数运行环境的影响,指向经常改变,使得开发变得困难和模糊,所以在封装sdk,写一些复杂函数的时候经常会用到this 指向绑定,以避免出现不必要的问题,call.ap ...
- js中更改this指向 以及回顾bind、call和apply
1.更改this指向 方法1:对this进行保存 var _this = this; 例: var _this = this; document.onclick = fu ...
- js基础进阶--关于Array.prototype.slice.call(arguments) 的思考
欢迎访问我的个人博客:http://www.xiaolongwu.cn Array.prototype.slice.call(arguments)的作用为:强制转化arguments为数组格式,一般出 ...
- 前端面试题目汇总摘录(JS 基础篇)
JS 基础 JavaScript 的 typeof 返回那些数据类型 object number function boolean undefined string typeof null; // o ...
- JS中----this的指向和如何修改this的指向
this this是js中的一个关键字,函数运行时自动生成的一个内部对象,只能在函数内部使用.我们要讨论的是 this 的指向. this就是函数运行时自动生成的一个内部对象 下面介绍一下几种情况下, ...
- 前端工程师面试问题归纳(一、问答类html/css/js基础)
一.参考资源 1.前端面试题及答案整理(一) 2.2017年前端面试题整理汇总100题 3.2018最新Web前端经典面试试题及答案 4.[javascript常见面试题]常见前端面试题及答案 5.W ...
- 前端面试题目汇总摘录(JS 基础篇 —— 2018.11.02更新)
温故而知新,保持空杯心态 JS 基础 JavaScript 的 typeof 返回那些数据类型 object number function boolean undefined string type ...
- JS基础-全方面掌握继承
前言 上篇文章详细解析了原型.原型链的相关知识点,这篇文章讲的是和原型链有密切关联的继承,它是前端基础中很重要的一个知识点,它对于代码复用来说非常有用,本篇将详细解析JS中的各种继承方式和优缺点进行, ...
随机推荐
- 07_NoSQL数据库之Redis数据库:Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存
事务处理 Redis对事务的支持目前还比较简单.Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令.当一个client在一个连接中发出mul ...
- Servlet读取文件的最好的方式
在java web 开发的时候不可避免的会读取文本信息,但是方式不同,所付出的代价也是不一样的,今天学到了一个比较好的实用性的技巧,拿来与大家分享一下. 读取属性配置文件 之所以说成是读取属性(pro ...
- python类:描述器Descriptors和元类MetaClasses
http://blog.csdn.net/pipisorry/article/details/50444769 描述器(Descriptors) 描述器决定了对象属性是如何被访问的.描述器的作用是定制 ...
- UNIX环境高级编程——线程
线程包含了表示进程内执行环境必需的信息,其中包括进程中标示线程的线程ID.一组寄存器值.栈.调度优先级和策略.信号屏蔽字.errno变量以及线程私有数据. 进程的所有信息对该进程的所有线程都是共享的, ...
- java中Error与Exception有什么区别
Error类和Exception类都继承自Throwable类. Error的继承关系: java.lang.Object java.lang.Throwable java.lang.Er ...
- C++对象模型(五):The Semantics of Data Data语义学
本文是<Inside the C++ Object Model>第三章的读书笔记.主要讨论C++ data member的内存布局.这里的data member 包含了class有虚函数时 ...
- PageContext ServletContext ServletConfig辨析
上面三个东西都是什么关系呀? 先看图 注意几点 1 GenericServlet有两个init方法# 2 GenericServlet既实现了ServletConfig方法,它自己由依赖一个Servl ...
- H5学习之旅-H5的格式化(4)
H5的格式设置: b代表是粗体 i斜体 big 字体变大 small变小 em强调 strong 加强和变粗差不多 sub 定义下标字 sup 定义上标字 ins 插入字 del 删除字 代码实例 & ...
- 新手自定义view练习实例之(二) 波浪view
本系列是为新手准备的自定义view练习项目(大牛请无视),相信在学习过程中,想学自定义view又无从下手,不知道做什么.本系列为新手提供了一系列自定义view的简单实例.看过理解之后,自己实现,相信会 ...
- ffdshow 源代码分析 7: libavcodec视频解码器类(TvideoCodecLibavcodec)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...