zoukankan      html  css  js  c++  java
  • 【原】javascript笔记之this用法

    javascript中的this学习起来相对复杂,最近花了点时间研究,总结起来大概这只有5种情况,相信只要熟悉这5种用法,基本是可以解决所有的this问题,文本不介绍this设计原理,只介绍用法,阅读本文,你需要了解javascript执行上下文环境,博主写这种文章的目的,主要还是给自己做下笔记,后续也会输出javascript的学习笔记。

    全局代码中的this & 调用普通函数中的this & this作为对象的属性值

    全局代码中的this ,永远是window。

    //全局环境下,this永远是window。
    console.info(this === window);// true
    
    //定义全局对象的属性
    this.cat = '猫'; // global.cat = '猫'
    console.info(cat); //
     
    //给一个无标示符变量赋值
    dog = '狗';
    console.info(this.dog); // '狗'
     
    //通过变量声明
    var bird = '鸟';
    console.info(this.bird); // '鸟'

    调用普通函数中的this,永远是window。

    function fn1() {
        this.cat = '包子'
        console.info(this);//Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
        console.info(this.cat);//包子
    }
    fn1() 

    this作为对象的属性值,永远是window。

    let obj = {
        cat : '猫宝宝',
        cat_father : this,
        cat_self : this.cat
    }
    console.info(obj.cat_father);//Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
    console.info(obj.cat_self);//undefined

    其它注意:任何时候不能改变this的值。

    //报错,任何时候不能改变this的值
    this = '鸟'

    构造函数中this

    函数作为构造函数用,那么其中的this就代表它即将new出来的对象。

    function Fn2() {
        this.cat = '包子',
        this.dog = '饺子'
        console.info(this);//Fn2 {cat: "包子", dog: "饺子"}
    }
    let fn2 = new Fn2();
    console.info(fn2.cat);//包子
    console.info(fn2.dog);//饺子

    原型链中this

    在构造函数的prototype中,this代表函数即将new出来的对象。

    function Fn3() {
        this.cat = '包子'
    }
    Fn3.prototype.getItem = function(){
        return this.cat;
    }
    let fn3 = new Fn3();
    console.info(fn3.getItem());//包子

    其实,不仅仅是构造函数的prototype,即便是在整个原型链中,this代表的也都是当前对象的值。

    函数作为对象的一个属性被调用

    函数作为对象的一个属性被调用,函数中的this指向调用它的对象,加深红色的这句话非常关键。

    let obj = {
        cat : '猫宝宝',
        fn : function(){
            console.info(this === obj);//true
            console.info(this.cat);//猫宝宝
        }
    }
    obj.fn()

    又如小程序中,使用Page(Object) 函数用来注册一个页面,接受一个 Object 类型参数,那么this指向该Object

    Page({
        data: {
            version: '1.0.1',
            cat:'张老板他妹'
        },
        onLoad: function () {
            console.info(this.data);//{version: "1.0.1", cat: "张老板他妹"}
        }
    })

    在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。因为this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境,但最终函数中的this指向调用它的对象

    let obj = {
        cat: '大猫',
        fn: function () { 
            console.info(this.cat) 
        }
    };
    //fn函数作为obj对象的一个属性被调用,在obj环境中执行,函数中的this指向该对象
    obj.fn() // 大猫
    
    
    var fn_new = obj.fn;
    var cat = '小猫';//全局环境的cat
    
    //fn函数赋值给变量fn_new的时候并没有执行,此时this指向window,那么执行fn_new()时,this.cat对应取值为window.cat
    fn_new() // 小猫

    再来一个例子,对象的中嵌套子对象,子对象的属性值为函数,函数被子对象调用,那么函数中的this指向子对象,也就是函数中的this指向调用它的对象

    let obj = {
        cat: '大猫',
        obj_in: {
            fn: function () { 
                console.info(this.cat) //undefined
            }
        }
    }
    //fn函数是被obj_in对象所调用,所以this指向的也obj_in对象
    obj.obj_in.fn();

    最后一个例子,对象的属性为函数,函数中嵌套函数,this放在嵌套函数中的情况

    let obj = {
        cat : '猫',
        fn : function(){
                function fn_in(){
                    console.info(this);//Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
                    console.info(this.cat);//undefined
                }
                //执行fn函数后,嵌套函数fn_in在fn环境中执行,回到文章中说的第一种情况,此时fn_in是普通函数,则它的this指向window
                fn_in();
        }
    }
    obj.fn()

    函数用call或apply或bind调用

    当一个函数被call和apply调用时,this的值就取传入的对象的值。

    let obj1 = {
        baobao : '猫'
    }
    let obj2 = {
        baobao : '羊'
    }
    let obj3 = {
        baobao : '鹅'
    }
    let fn3 =  function(){
        console.info(this.baobao);
    }
    fn3.apply(obj1);//
    fn3.call(obj2);//
    fn3.bind(obj3)();//

    同函数作为对象的一个属性被调用一样,函数fn4_in是在obj.fn4内部定义的,所以它仍然是一个普通的函数,this仍然指向window。

    let obj3 = {
        baobao : '猫'
    }
    let fn4 =  function(){
        function fn4_in(){
            console.info(this.baobao);//undefined
        }
        fn4_in()
    }
    fn4.apply(obj3);

    参考资料

    http://www.ruanyifeng.com/blog/2018/06/javascript-this.html

    http://www.cnblogs.com/TomXu/archive/2012/01/17/2310479.html

    http://www.cnblogs.com/wangfupeng1988/p/3988422.html

  • 相关阅读:
    递归函数及Java范例
    笔记本的硬盘坏了
    “References to generic type List should be parameterized”
    配置管理软件(configuration management software)介绍
    WinCE文件目录定制及内存调整
    使用Silverlight for Embedded开发绚丽的界面(3)
    wince国际化语言支持
    Eclipse IDE for Java EE Developers 与Eclipse Classic 区别
    WinCE Heartbeat Message的实现
    使用Silverlight for Embedded开发绚丽的界面(2)
  • 原文地址:https://www.cnblogs.com/PeunZhang/p/9830623.html
Copyright © 2011-2022 走看看