博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
杂七杂八的前端基础01——函数作用域
阅读量:7291 次
发布时间:2019-06-30

本文共 2167 字,大约阅读时间需要 7 分钟。

首先我们来声明一个js对象person:

var person = {    talk() {        console.log("I am talking...");    }};复制代码

然后调用person对象的talk方法:

person.talk();复制代码

结果如下:

没有任何问题,然后我们将person对象的talk方法赋值给一个全局变量talk,并调用这个全局的talk方法:

var talk = person.talk;talk();复制代码

结果如下:

和之前的执行结果相同。

现在我们来给person对象新增属性name和方法sayName,修改之后的person对象如下:

var person = {    name: 'xiaoming',    talk() {        console.log("I am talking...");    },    sayName() {        console.log("My name is " + this.name);    }}复制代码

调用person对象的sayName方法:

person.sayName();复制代码

结果如下:

没有任何问题,输出的name是person对象的name属性,然后我们将person对象的sayName方法赋值给一个全局变sayName,并调用这个全局的sayName方法:

var sayName = person.sayName;sayName();复制代码

结果如下:

我们发现此时没有找到name,输出
undefined,这是由于我们调用sayName方法时,是在全局作用域下调用的该方法,对比一下:

//调用person对象的sayName方法:person.sayName();调用全局的sayName函数,浏览器环境下相当于调用:window.sayName();复制代码

而此时顶级对象window下并没有name属性,所以输出undefined

这里多提几句,之前关于this的分析全是基于浏览器运行环境下的,如果在node下声明函数,this指向的是global对象,而在该node模块中声明的全局变量属于该模块,不属于global对象,如果想要将全局变量绑定到global,那么需要在不使用var或者let等关键词,就可以挂载到global上了。

我们再拓展一下,如果在定时器中使用this是指向什么作用域呢?、 在person对象中新增一个方法sayNameLater,修改之后的person对象如下:

var person = {    name: 'xiaoming',    talk() {        console.log("I am talking...");    },    sayName() {        console.log("My name is " + this.name);    },    sayNameLater() {        setTimeout(function() {            console.log("My name is " + this.name);        },1000);    }}复制代码

调用person对象的sayNameLater方法:

person.sayNameLater();复制代码

结果如下:

我们发现此时没有找到name,输出
undefined,这是由于我们在使用定时器时,函数中的this会指向window对象(浏览器环境下),如果我们此时声明全局变量name并赋值:

var name = "xiaohong";复制代码

再调用person对象的sayNameLater方法:

person.sayNameLater();复制代码

结果如下:

使用定时器时,函数中的this会指向window对象,即使我们使用对象方法而不是函数,this依然会指向window对象。现在person对象不变,全局变量name不变,在定时器中调用person对象的sayName方法:

var name = "xiaohong";var person = {    name: 'xiaoming',    talk() {        console.log("I am talking...");    },    sayName() {        console.log("My name is " + this.name);    },    sayNameLater() {        setTimeout(function() {            console.log("My name is " + this.name);        },1000);    }}setTimeout(person.sayName, 1000);复制代码

结果如下:

可以看到使用的仍然是全局变量name,这是由于计时器在解析第一个参数的时候使用eval执行,相当于我们最开始说的,将函数的方法赋值给一个变量,并执行该变量方法,所以作用域依然是全局。

转载地址:http://lpcjm.baihongyu.com/

你可能感兴趣的文章
转:如何正确彻底删除webpack 全局或是局部?
查看>>
【Python】Symbol Review
查看>>
电脑 F键(功能键)的具体作用
查看>>
004-软件质量保证&QC/QA
查看>>
选择排序的实现以及性能测试
查看>>
基于snowfall的玫瑰花瓣飘落效果
查看>>
linux之cut用法
查看>>
结交比自己优秀的人
查看>>
Home键和back键下 Activity的生命周期变化
查看>>
用MotoMidMan给L7批量安装java程序
查看>>
C语言中main函数之前可以进行赋值作吗?
查看>>
WKWebView Cookie注入
查看>>
组合数据类型,英文词频统计
查看>>
【3】火狐中: radio被点击以后,重刷页面,不会选择默认的radio
查看>>
读书笔记:《HTML5开发手册》-- 现存元素的变化
查看>>
mongodb php
查看>>
C#限速下载网络文件
查看>>
在operator=中处理”自我赋值“
查看>>
纯CSS实现三列DIV等高布局
查看>>
Web应用架构-DNS
查看>>