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

  • 相关阅读:
    android 添加图片时错误:android libpng error: Not a PNG file
    hdu4553
    zoj2706
    zoj3349
    zoj3606
    主席树 静态区间第k大
    主席树:动态 Kth
    zoj3633
    zoj3381
    zoj 3540
  • 原文地址:https://www.cnblogs.com/PeunZhang/p/9830623.html
Copyright © 2011-2022 走看看