zoukankan      html  css  js  c++  java
  • JavaScript 中 this 的用法

    在 JavaScript 中,this 是动态绑定,或称为运行期绑定的。一般而言,在Javascript中,this 指向函数执行时的当前对象。

    由于其运行期绑定的特性,JavaScript 中的 this 可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下几种方式:没有明确的调用对象,作为对象方法调用,使用 new 关键字作为构造函数调用,和使用 apply、 call 和 eval 调用。

    没有明确的当前对象时

    当没有明确的执行时的当前对象时,this 指向全局对象 window

    纯粹的函数调用

    举个栗子

    1
    2
    3
    4
    5
    6
    var x = 1;
    function test(){
    var x = 2;
    alert(this.x);
    }
    test(); // 1

    再看个复杂的栗子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    var name = "window";

    var Bob = {
    name: "Bob",
    showName: function(){
    alert(this.name);
    }
    };

    var Tom = {
    name: "Tom",
    showName: function(){
    var fun = Bob.showName;
    fun();
    }
    };

    Tom.showName();  //window

    其实也不复杂,只要按照上面那句话来判断就行。

    setTimeout、setInterval和匿名函数

    在浏览器中 setTimeoutsetInterval 和匿名函数执行时的当前对象是全局对象 window,这条可以看成是上一条的一个特殊情况。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var name = "Bob";  
    var nameObj = {
    name : "Tom",
    showName : function(){
    alert(this.name);
    },
    waitShowName : function(){
    setTimeout(this.showName, 1000);
    }
    };

    nameObj.waitShowName(); // Bob

    setTimeout 可以看做是一个延迟执行的匿名函数。

    1
    2
    3
    4
    5
    waitShowName : function(){  
    function(__callback){
    __callback();
    }(this.showName);
    }

    由于匿名函数的当前对象是 window,所以当在该匿名函数中运行回调函数时,回调函数的 this指向了 window,所以 alert 出来 window.name 。

    作为对象方法调用时

    使用这种调用方式时,this 被自然绑定到该对象。

    通常情况

    1
    2
    3
    4
    5
    6
    7
    8
    var text = 'window'
    var obj = {
    text: 'obj',
    foo: function(){
    console.log(this.text);
    }
    }
    obj.foo(); // obj

    内部函数调用

    但是,如果在 obj 的 foo() 内部再声明一个函数,在内部函数中调用 this,像下面这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    'use strict';
    var obj = {
    text: 'hello world',
    foo: function(){
    return function(){
    console.log(this.text);
    }()
    }
    }

    obj.foo();
    // Uncaught TypeError: Cannot read property 'text' of undefined

    这是因为 this 指针只在 foo 方法的函数内指向 obj ,在函数内部定义的函数, this 又指向undefined 了!(在非 strict 模式下,它重新指向全局对象 window !)

    修复的办法是用一个 that 变量首先捕获 this :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    'use strict';
    var obj = {
    text: 'obj',
    foo: function(){
    var that = this;
    return function(){
    console.log(that.text);
    }()
    }
    }
    obj.foo(); // obj

    三种特殊情况

    new关键字 - 作为构造函数调用时

    所谓构造函数,就是通过这个函数生成一个新对象。这时,this 就指这个新对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function Person(__name){
    this.name = __name;
    // this 指向使用该构造函数构造的新对象
    }
    Person.prototype.show = function(){
    alert(this.name);
    }

    var Bob = new Person("Bob");
    Bob.show(); //Bob

    apply 和 call

    在 JavaScript 中函数也是对象,对象则有方法,apply() 和 call() 就是函数对象的方法。它们能够强制改变函数执行时的当前对象,让 this 指向其他对象。

    apply() 接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是 Array,表示函数本身的参数。call() 与 apply() 的唯一区别就是把函数本身的参数一个个传入。

    1
    2
    3
    // 对普通函数调用,通常把 this 绑定为 null
    Math.max.apply(null, [3, 5, 4]); // 5
    Math.max.call(null, 3, 5, 4); // 5

    举个使用 apply() 改变当前对象的栗子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var name = "window";

    var someone = {
    name: "Bob",
    showName: function(){
    alert(this.name);
    }
    };

    var other = {
    name: "Tom"
    };

    someone.showName.apply(); // window
    someone.showName.apply(other); // Tom

    apply() 的参数为空时,默认调用全局对象。

    eval

    对于 eval 函数,其执行时候似乎没有指定当前对象,但实际上其 this 并非指向 window,因为该函数执行时的作用域是当前作用域,即等同于在该行将里面的代码填进去。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var name = "window";

    var Bob = {
    name: "Bob",
    showName: function(){
    eval("alert(this.name)");
    }
    };

    Bob.showName(); //Bob

    参考

    1. 对 js 中 this、apply、call 和闭包的理解
    2. Javascript中this关键字详解
    3. 深入浅出 JavaScript 中的 this
    4. Javascript的this用法
  • 相关阅读:
    不参加IT培训,如何通过自学的方式成功转行?(蜗牛学院)
    惠普电脑win10关闭自动调节亮度
    原生Ajax发送get、post请求每一步
    HTML5的web 存储localStorage、sessionStorage
    node + multer存储element-ui上传的图片
    html块级元素的水平垂、直居中的方式
    vuex之Mutation(三)
    mint ui的tabBar监听路由变化实现tabBar切换
    Vue使用better-scroll左右菜单联动
    vuex之getter(二)
  • 原文地址:https://www.cnblogs.com/ilinuxer/p/5244126.html
Copyright © 2011-2022 走看看