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中的各种继承方式和优缺点进行, ...
随机推荐
- 最简单的基于FFmpeg的AVfilter例子(水印叠加)
===================================================== 最简单的基于FFmpeg的AVfilter例子系列文章: 最简单的基于FFmpeg的AVfi ...
- java开源项目之IQQ学习记录之项目环境搭建与启动
本文链接地址:http://blog.csdn.net/sushengmiyan/article/details/18779727 作者:sushengmiyan 现在就码字说说今天晚上搞定的一个项目 ...
- Leetcode_13_Roman to Integer
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41486885 通过本文你可能学到的知识如下: (1)理解本 ...
- CSS引入
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- python调用数据库并查询
http://blog.csdn.net/pipisorry/article/details/48024795 python调用数据库命令 conn = sqlite3.connect(". ...
- 【一天一道LeetCode】#52. N-Queens II
一天一道LeetCode系列 (一)题目 Follow up for N-Queens problem. Now, instead outputting board configurations, r ...
- VS2010中NET4项目中使用LOG4NET办法
两年以前项目中是用的log4net.dll是net2.0环境下面的,最近在官网http://logging.apache.org/log4net/download_log4net.cgi找到了net4 ...
- 更改EBS R12中forms的模式Servlet/Socket
EBS R12中forms的模式有:Servlet mode 和 Forms Socket mode 当我们完成Oracle EBS R12套件的快速安装后,forms的默认配置是Servlet mo ...
- 自己动手写web框架----1
本文可作为<<自己动手写struts–构建基于MVC的Web开发框架>>一书的读书笔记. 一个符合Model 2规范的web框架的架构图应该如下: Controller层的Se ...
- iOSAPP启动效果复杂动画之抽丝剥茧
一.前言 随着开发者的增多和时间的累积,AppStore已经有非常多的应用了,每年都有很多新的APP产生.但是我们手机上留存的应用有限,所以如何吸引用户,成为产品设计的一项重要内容.其中炫酷的动画效果 ...