欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【原】javascript学习笔记之this用法

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

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指向该对象。这种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) 
    }
};

var fn_new = obj.fn;
var cat = '小猫';//全局环境的cat

//fn函数作为obj对象的一个属性被调用,在obj环境中执行,函数中的this指向该对象
obj.fn() // 大猫

//fn_new函数被调用执行时,在全局环境即window执行,此时this指向window,那么this.cat全局环境的cat
fn_new() // 小猫

再来一个例子,对象的属性为函数,函数中嵌套函数,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