一、this指向的详解

概括:this的指向到底是指向哪里?通常来说,只有当函数执行的时候才可以确定this指向的到底是谁,简单的也可以这么说:this最终指向的是那个调用它的对象。

常见的一般有以下几种情况:

第一种:在一个函数中有this,但是函数没有被上一级对象所调用,所以此时的this指向的是window(注意在严格模式下则不是),如以下代码:

function blue() {
var blue = "蓝源";
console.log(this.blue);//undefind
console.log(this);//window
}
blue();//this指向调用它的那个对象,在这里相当于window

第二种:在函数中有一个this,而且该函数被上一级对象所调用,所以此时的this指向的是调用该函数的上一级对象,如以下代码:

var o = {
name: "blue",
fn: function(){
console.log(this.name);//blue
console.log(this);//指向o对象
}
}
o.fn();//此时this指向的是调用函数的对象o。

第三种:有一个函数中有this,函数中有多个对象,尽管这个函数是被最外层的对象调用,但是其中的this指向的只是它的上一级对象,如以下代码:

var o = {
name: "blue",
a: {
fn: function(){
console.log(this.name);//undefind,这里有两个对象o和a,调用的时候都指向上一层对象a,这里找不到声明的name
}
},
fn1: function(){
console.log(this.name);//blue
}
}
o.fn1();
o.a.fn();

第四种(特殊情况):如果函数中有return,而且return返回的是一个对象,那么调用时候的this指向不再是指向调用这个函数的实例了,而是指向这个函数返回的对象,如以下代码:

function fn() 
{
this.name = 'blue';
return {};
}
var a = new fn;
console.log(a.name); //undefined,这里指向的是return返回的对象,是一个空对象

二、改变this指向的方法

第一种:使用call()

var a = {
user:"blue",
fn:function(){
console.log(this.user); //blue
}
}
var b = a.fn;
b.call(a); //若不用call,则b()执行后this指的是Window对象

call方法除了第一个参数以外还可以添加多个参数,如下:

var a = {
user:"blue",
fn:function(c,d){
console.log(this.user); //blue
console.log(e+ee); //3
}
}
var b = a.fn;
b.call(a,1,2);

第二种:使用apply()

var a = {
user:"blue",
fn:function(){
console.log(this.user); //blue
}
}
var b = a.fn;
b.apply(a);

apply方法和call方法很类似,也可以接收多个参数,但是第二个参数必须是数组,如下:

var a = {
user:"blue",
fn:function(e,ee){
console.log(this.user); //blue
console.log(c+d); //11
}
}
var b = a.fn;
b.apply(a,[10,1]);

第三种:使用bind()

bind和call,apply的使用方法有些不同,如果我们还是按照上面的方法写代码,会发现一些问题,如下:

var a = {
user:"blue",
fn:function(){
console.log(this.user);
}
}
var b = a.fn;
b.bind(a); //代码没有被打印

为什么代码没有被打印呢?这就是不同的地方所在,实际上执行bind之后返回的是一个函数,想下面这样写才是正确的:

var a = {
user:"blue",
fn:function(){
console.log(this.user); //blue
}
}
var b = a.fn;
var c = b.bind(a);
c();

bind()方法也可以接收多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的,如下:

var a = {
user:"blue",
fn:function(e,d,f){
console.log(this.user); //blue
console.log(e,d,f); //10 1 2
}
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);

总结:

call(),apply()以及bind()方法都可以改变this指向,只是所使用的场景有点不一样,bind()改变后的函数想什么时候调用就什么时候调用,call和apply都是改变指向后立即调用此方法。

JavaScript-改变this指向的更多相关文章

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

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

  2. $.on()方法和addEventListener改变this指向

    jQuery $.on()方法和addEventListener改变this指向 标签(空格分隔): jQuery JavaScript jQuery $.on() jq的绑定事件使用$([selec ...

  3. setTimeout改变this指向(****************************************)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. 前端js中this指向及改变this指向的方法

    js中this指向是一个难点,花了很长时间来整理和学习相关的知识点. 一. this this是JS中的关键字, 它始终指向了一个对象, this是一个指针; 参考博文: JavaScript函数中的 ...

  5. this(this的4种指向和改变this指向的方式)

    this是Javascript语言的一个关键字. 随着函数使用场合的不同,this的值会发生变化.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 1.this指向的形式4种 a.如果是 ...

  6. javascript中this指向的问题

    javascript中this只有函数执行时候才能确定到底指向谁,实际this最终指向是那个调用它的对象. 1,匿名函数中的this——window function foo(){ var lastN ...

  7. JS中this指向问题和改变this指向

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  8. Javasript中this指向问题和改变this指向的方法

    在学习javascript中我们往往会被this的指向问题弄的头昏转向,今天我们就来学习一下this的指向问题,和改变this指向的方法. 一.this的指向问题 在学习this的指向问题之前我们需要 ...

  9. 可以改变this指向的方法

    this一般指向的是当前被调用者,但也可以通过其它方式来改变它的指向,下面将介绍三种方式: 1.call用作继承时: function Parent(age){ this.name=['mike',' ...

  10. 图解javascript中this指向

    JavaScript 是一种脚本语言,支持函数式编程.闭包.基于原型的继承等高级功能.JavaScript一开始看起来感觉会很容易入门,但是随着使用的深入,你会发JavaScript其实很难掌握,有些 ...

随机推荐

  1. linux 操作系统级别监控 vmstat/dstat 命令

    vmstat命令综合了CPU.进程.内存.磁盘IO等信息 命令:vmstat 1       表示vmstat每2秒采集数据,一直采集,直到我结束程序 vmstat 2 1    表示每个两秒采集一次 ...

  2. [C++] C++中的常用库

    转载自:C++常用库 C++ 资源大全 关于 C++ 框架.库和资源的一些汇总列表,内容包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++标准库,包 ...

  3. AMD vs. CommonJS?

    js开发者对js模块加载的尝试和创新从来都没有停止过,尤其是当nodejs的出现后,模块化加载的必要性更加凸显.本文不讨论如何在nodejs环境来模块化加载(创造者已经利用commonJS机制解决), ...

  4. 数据结构之二叉树篇卷二 -- 二叉树递归遍历(With Java)

    一.先序递归遍历(Preorder Recursive Traversal) 1.1 算法 首先需要明确的是这里的序是针对 root 节点而言的.故先序即先“访问”根节点,其次“访问”其左右节点. 1 ...

  5. C++ 生成随机数 srand()和rand()

    1. rand() rand(产生随机数)表头文件: #include<stdlib.h>定义函数 :int rand(void) 函数说明 :因为rand() 的内部实现是用线性同余法做 ...

  6. Android导入Burp Suite证书抓包HTTPS

    需求 Android APP安全测试时,主要工作分为: APK安全 业务安全 APK安全这里不讨论,我说说业务安全,因为大部分的业务校验逻辑还是放在Servier端,这里就会涉及到网络通信了.因此网络 ...

  7. Asteroids POJ - 3041 二分图最小点覆盖

       Asteroids POJ - 3041 Bessie wants to navigate her spaceship through a dangerous asteroid field in ...

  8. 完整的Android MVP开发之旅

    开发背景 最近是在做一个与健身相关的APP,里面有训练器模块基本功能是按照特点动作的演示和描述来引导用户完成训练.在第一个版本时由于没接触过些类项目与功能花了几周的时间大概1500行代码才完成这个功能 ...

  9. mysql创建数据库指定字符集和校对规则

    mysql创建数据库的语法格式: CREATE DATABASE [IF NOT EXISTS] <数据库名> [[DEFAULT] CHARACTER SET <字符集名>] ...

  10. Flask基础(07)-->正则自定义转换器

    正则自定义转换器 为什么要自定义正则转换器? 因为默认转换器太过于笨重,往往不能满足我们实际业务的需求,这时候我们就需要自定义正则转换器了. 那么我们怎么自定义正则转换器呢? from flask i ...