下面小编就为大家带来一篇深入理解 js 函数的作用域与 this 指向。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
函数的作用域与 this 指向是 js 中很重要的一部分,理清这点东西需要个逻辑,看看我的逻辑怎么样...
下面是个提纲,可以直接挑你感兴趣的条目阅读。
• 函数的定义方式:直接定义(window 下,内部定义),对象的方法,对象原型的方法;
• 函数的调用方式:直接调用,call/apply,with
• 对于直接定义的函数和对象的方法,作用域默认状态下是它的定义处的作用域链。
• 对于直接定义的函数,this 指向 window。
• 对于对象的方法,this 指向实例化对象(对应于实例化对象默认返回 this 的情况)。
• 用 call/apply 改变方法的 this 指向
• 在函数或方法的定义时可以通过 with 改变其作用域链。
下面分开来具体说说:
函数的定义,如提纲中提到的可以分为两种:直接定义(window 下,内部定义),对象的方法(或对象原型的方法)。从下面的示例代码中可以看到函数 fn1 与 fn2 以及对象的方法 doFunction 在函数使用 name 时 name 的值来自相应的域。
- var name = 'window下的name<br/>';
- var resultCon;
- function fn1() {
- resultCon.innerhtml += name;
- }
- function MyObj() {
- var name = 'MyObj下的name<br/>';
- this.doFunction = function() {
- resultCon.innerHTML += name;
在使用 name 的值时将 "name" 用 "this.name" 来代替会出现什么情况呢,看下例:
- var name = 'window下的name<br/>';
- var resultCon;
- function fn1() {
- resultCon.innerHTML += this.name;
- }
- function MyObj() {
- var name = 'MyObj下的name<br/>';
- this.doFunction = function() {
- resultCon.innerHTML += this.name;
从结果来看可以验证提纲中的第 4 和 5 条,也可以看到 this 和作用域是两套分离的链,遵循个自的变量查询逻辑,具体的查询逻辑在下面的性能分析中会提到,如果是新手建议先看一下 "js 的作用域链" 方面的基础知识。
关于函数的调用方法,我用下面的方示例说明提纲中的第 2、6 条:
- var name = 'window下的name<br/>';
- var resultCon;
- function fn1() {
- resultCon.innerHTML += this.name;
- }
- function MyObj() {
- var name = 'MyObj下的name<br/>';
- this.doFunction = function() {
- resultCon.innerHTML += this.name;
调用时 call 和 apply 的使用是为了改变被调用函数的 this 指向。with 的使用是为了改变被调用函数中变量的查询域。我们把上例中的 call 和 name 前的 this 去掉再加上 with 来演示 with 的作用。
- var name = 'window下的name<br/>';
- var resultCon;
- function fn1(myScope) {
- with (myScope) {
- resultCon.innerHTML += name;
- }
- }
- function MyObj(myScope) {
- var name = 'MyObj下的name<br/>';
看到 with 的使用并不方便,需要在被调用函数中添加 with,有人可能想能不能向下面那样调用来整体改变变量作用域而不去改变被调用函数呢?
- with (myScope) {
- fn1();
- fn2();
- var obj = new MyObj();
- obj.doFunction();
- }
很遗憾,不可以!所以在一些成熟的框架中随处可见 call 和 apply 的使用,却很少用到 with,在用 JSHint 检测 js 语法的时候 with 处都标了小红点,在一些 js 编码指导中也建议尽量少用 with,因为 with 改变了变量的默认查询链,所以会给后期的维护人员一些困惑,还有性能方面的一些考虑,请慎用 with。
以上这篇深入理解 js 函数的作用域与 this 指向就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持 phperz。
来源: http://www.phperz.com/article/17/0227/265361.html