JavaScript 中一句话的思索:this是函数在执行时所处的作用域

最近看《JavaScript高级程序设计》一书,在讲到函数中对象一节时,提到了this对象,中有一句“this是函数在执行时所处的作用域”,译者注:原书的提法并不准确,详见http://www.cn-cuckoo.com/2010/05/08/about-one-sentence-of-pro-js-2nd-1626.html。于是我就看了,但下面有几个人评论说原书是正确的,还给出了一些代码,对结果不是很懂。

几经迷茫才理清思路,现整理如下。

 

1、函数必须被对象所调用,若直接使用一个已经定义的函数,则它是被全局对象Global调用;

2、函数被调用时,直接引用变量的,遵循变量的函数域查找法则,由这个变量定义的最近函数域开始,依次向外层函数域查找同名变量,直到全局域,也即全局对象;

3、函数被调用时,若通过this调用,则会通过对象的原型链查找;因为this就是直接引用到了调用该函数的对象。

 

根据上面这三个法则,就不会判错了。下面贴上代码:【Download

 

// Test for basic function scope
var value = 'global scope';
function getValue() {
    var value = 'function scope';
    function _getValue() {
        return value;
    }
    return _getValue();
}
function getThisValue() {
    var value = 'function scope';
    function _getValue() {
        return this.value;
    }
    return _getValue();
}
alert(getValue());                  // function scope /* called by window */
alert(getThisValue());              // global scope /* called by window */

// Test for prototype chain with property
function Base(){
    this.value = 'base scope';
    this.getValue = function() {
        return value;
    };
    this.getThisValue = function() {
        return this.value;
    }
};
var objBase = new Base();
alert(objBase.getValue());          // global scope /* this.value has value 'base scope', bug it is a property but not a varable. */
alert(objBase.getThisValue());      // base scope
var objChild = new Base();
alert(objChild.getValue());         // global scope
alert(objChild.getThisValue());     // base scope /* lookup through property chain. */
objChild.value = 'child scope';
alert(objChild.getValue());         // global scope
alert(objChild.getThisValue());     // child scope

// Test for prototype chain with variable in function
function Base2(){
    var value = 'base function scope';
    this.getValue = function() {
        return value;
    };
    this.getThisValue = function() {
        return this.value;
    }
};
var objBase = new Base2();
alert(objBase.getValue());          // base function scope
alert(objBase.getThisValue());      // undefined /* objBase called getThisValue, but has no property named value. */
var objChild = new Base2();
alert(objChild.getValue());         // base function scope
alert(objChild.getThisValue());     // undefined
objChild.value = 'child scope';
alert(objChild.getValue());         // base function scope
alert(objChild.getThisValue());     // child scope
posted @ 2012-09-20 03:33  王晗  阅读(326)  评论(0编辑  收藏  举报