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