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的作用的更多相关文章

  1. js基础梳理-关于this常见指向问题的分析

    首先,依然回顾<js基础梳理-究竟什么是执行上下文栈(执行栈),执行上下文(可执行代码)?>中的 3.执行上下文的生命周期 3.1 创建阶段 生成变量对象(Variable object, ...

  2. js基础篇——call/apply、arguments、undefined/null

    a.call和apply方法详解 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象 ...

  3. js中改变this指向的call、apply、bind 方法使用

    前言: 由于js 中this的指向受函数运行环境的影响,指向经常改变,使得开发变得困难和模糊,所以在封装sdk,写一些复杂函数的时候经常会用到this 指向绑定,以避免出现不必要的问题,call.ap ...

  4. js中更改this指向 以及回顾bind、call和apply

    1.更改this指向 方法1:对this进行保存            var _this = this; 例: var _this = this;     document.onclick = fu ...

  5. js基础进阶--关于Array.prototype.slice.call(arguments) 的思考

    欢迎访问我的个人博客:http://www.xiaolongwu.cn Array.prototype.slice.call(arguments)的作用为:强制转化arguments为数组格式,一般出 ...

  6. 前端面试题目汇总摘录(JS 基础篇)

    JS 基础 JavaScript 的 typeof 返回那些数据类型 object number function boolean undefined string typeof null; // o ...

  7. JS中----this的指向和如何修改this的指向

    this this是js中的一个关键字,函数运行时自动生成的一个内部对象,只能在函数内部使用.我们要讨论的是 this 的指向. this就是函数运行时自动生成的一个内部对象 下面介绍一下几种情况下, ...

  8. 前端工程师面试问题归纳(一、问答类html/css/js基础)

    一.参考资源 1.前端面试题及答案整理(一) 2.2017年前端面试题整理汇总100题 3.2018最新Web前端经典面试试题及答案 4.[javascript常见面试题]常见前端面试题及答案 5.W ...

  9. 前端面试题目汇总摘录(JS 基础篇 —— 2018.11.02更新)

    温故而知新,保持空杯心态 JS 基础 JavaScript 的 typeof 返回那些数据类型 object number function boolean undefined string type ...

  10. JS基础-全方面掌握继承

    前言 上篇文章详细解析了原型.原型链的相关知识点,这篇文章讲的是和原型链有密切关联的继承,它是前端基础中很重要的一个知识点,它对于代码复用来说非常有用,本篇将详细解析JS中的各种继承方式和优缺点进行, ...

随机推荐

  1. ROS_Kinetic_01 在ubuntu 16.04安装ROS Kinetic 2017.01更新

    ROS_Kinetic系列学习(一),在ubuntu 16.04安装ROS Kinetic. Celebrating 9 Years of ROS! ubuntu16.04已经发布半年多了,ROS的K ...

  2. 【Mac】Mac OS X 安装GNU命令行工具

    macos的很多用户都是做it相关的人,类unix系统带来了很多方面,尤其是经常和linux打交道的人. 但是作为经常使用linux 命令行的人发现macos中的命令行工具很多都是bsd工具,跟lin ...

  3. 08_Android中的SimpleAdapter的使用

     1 目的界面 2.编写Android清单文件 <?xml version="1.0" encoding="utf-8"?> <manif ...

  4. Linux搭建GIT 使用Eclipse创建并上传Git项目 EGit操作

    Linux搭建Git 1. gitblit服务器文档 http://gitblit.com/setup_go.html 2. 安装jdk 参考 http://blog.csdn.net/jerome_ ...

  5. awk字符串函数及其意义

     awk字符串函数及其意义 awk提供了强大的内置字符串函数,用于实现文本的字符串替换.查找以及分隔等功能. awk字符串函数主要有:gsub.index.length.match.split.sub ...

  6. JAVA之旅(二)——if,switch,for,while,do while,语句嵌套,流程控制break , continue ,函数,重载的示例总结

    JAVA之旅(二)--if,switch,for,while,do while,语句嵌套,流程控制break , continue ,函数,重载的示例总结 JAVA的思想真的很重要,所以要专心的学-- ...

  7. Warning: $HADOOP_HOME is deprecated解决方法

    启动Hadoop时报了一个警告信息,我的系统是CentOS,安装的Hadoop版本是hadoop1.2.1,具体警告信息如下: [root@m1 hadoop-1.2.1]# bin/start-al ...

  8. 集群通信组件tribes之应用程序处理入口

    Tribes为了更清晰更好地划分职责,它被设计成用IO层和应用层,IO层专心负责网络传输方面的逻辑处理,把接收到的数据往应用层传送,当然应用层发送的数据也是通过此IO层发送,数据传往应用层后必须要留一 ...

  9. cocos2d-x action执行完毕的回调

    cocos2d-x action执行完毕的回调 MySprite::createOne() { .... //  MUST add to sheet firstly        spriteShee ...

  10. Oracle EBS订单的流程(Order->AR)

    from:http://blog.csdn.net/pan_tian/article/details/7693447 基本流程 创建订单 路径:Order Management > Orders ...