首页 > 关于JS的特权方法的一点问题

关于JS的特权方法的一点问题

<script type="text/javascript">
    function zdw(){ 
        var name="asasas";
        function showname(){ 
            console.log(this);//window
            console.log(this.name);
        }
        this.show=function(){
            showname(); 
            console.log(this);//zdw 
        } 
    }  
    // zdw.prototype.setname=function(str){
    //  name=str;
    // } //为什么这里name就变成在window下了
    var zzddww=new zdw();
    // zzddww.setname("22222");
    zzddww.show(); 
</script>

1:为什么showname()的this指向window
2:为什么
zdw.prototype.setname=function(str){
name=str;
}
这个后name就是放在了window下


问题一:
this是进入上下文时确定,在一个函数代码中,这个值可以根据不同的调用方式完全不同。

影响了函数代码中this值的变化有几个因素:

首先,在通常的函数调用中,this是由激活上下文代码的调用者来提供的,即调用函数的父上下文(parent context )。this取决于调用函数的方式。

为了在任何情况下准确无误的确定this值,有必要理解和记住这重要的一点。正是调用函数的方式影响了调用的上下文中的this值,没有别的什么(我们可以在一些文章,甚至是在关于javascript的书籍中看到,它们声称:“this值取决于函数如何定义,如果它是全局函数,this设置为全局对象,如果函数是一个对象的方法,this将总是指向这个对象。–这绝对不正确”)。继续我们的话题,可以看到,即使是正常的全局函数也会被调用方式的不同形式激活,这些不同的调用方式导致了不同的this值。

摘自 深入理解JavaScript系列(13):This? Yes,this! 可以详细看下

问题二:

zdw.prototype.setname=function(str){
    name=str;//全局变量  - 类似于 public的概念  - 写法一
    var name=str;//局部变量  -  类似于private的概念 - 写法二
    this.name=str;//会在 原型链上  -  类似于protected的概念 - 写法三
}

不知道你有没有 学过 C、C++之类的语言?
上面的注释只是举例,javascript的 使用的是 词法作用域,即任何变量在它写下的时候,它的作用域就定下来了;

在调用setname时, 函数会生成一个叫作用域链的东西;你可以具体去看下作用域链的概念;
它是一个多级的东西,setname在查找name这个变量会先看它自己的 function中有没有 name这个变量,没有就会去 包含 它的的地方找,你这里就是 window 了;有时会有 function 嵌套 function 的情况,它就去包住它的那个 function 找,没找到 就一级一级往外找 直到 Object.prototype.name 为止,那么就会报undefined错误了;

下面回答你的问题:
写法一: name=str; 这里不加 var 它就去找 name这个变量, 结果没找到,就去window下创建了一个 name 的变量;
写法二: var name=str; 加了var 就简单多了, 只在自己这个function下生成一个 name变量; 别的function都无法找到或修改它;
写法三: this.name=str; 通常这种用法 会很多,这里的name 可以在 zdw.prototype.functionName 这种形式的 functionName 中共享,所以有点 protected 的概念


最后补充句: javascript 一切皆对象,理解这个很多问题就懂了; 看你的问题,我猜你变量、函数、数组、对象、函数 这些概念还没理解;直接来学 类 其实很多东西会一知半解的,这块可以先不急的; 变量、函数、数组、对象、函数 这些是基础。


调用函数的时候上下文已经是window了


function showname()
这段代码即便是写在zdw的定义中, 也并没有让它成为zdw的成员, 而无主的函数在运行时的this都是window
其实你期望的写法是这样
this.showname = function(){}
这样showname就是zdw类的成员了, 运行时this指向zdw类的事例


函数中的this指向调用他的对象,
1.console.log(),其实是window.console.log(),而不是你构造函数中的方法。
2.作为构造函数,你是new出来的,this当然指向调用他的对象。


thisJavaScript语言精粹里面有讲到,在chapter 4 - Function, Invocation。
里面讲了4种pattern。题中属于其中2种,function invocation patternconstructor invocation pattern

下面是原理,详细的翻译文章看楼上介绍那篇。

ECMAScript 3rd:
this的值取决于你怎么调用他。原理就是是由reference type所决定的。

reference type即是()左边的identifier。identifier有function name, variable name, object property。比如题中的showName()

reference type又是由他自己的base object所决定的。即,看identifier是属于哪个base object。

也就是说,this的值取决于reference type的base object。


根据上面,当调用showName()的时候,在()左边的identifier是showName, 而showName是属于他所在的anynomous function的active object里。也就是base object是active object,在ECMAScript 3里面,此时this的值是global object,但ECMAScript 5中已经fixed, 为undefined

zzddww.show()的时候,在()左边的是identifier是show,而show的base object是zzddww这个object,所以this就是zzddww

【热门文章】
【热门文章】