注意代码中的变量名和function名的关系,书写一定要分清楚各个变量的词法作用域。
第一种情况,虽然名字相同,但词法作用域不同,不相关系。
function Tweak() { // 这里的Tweak是window的一个全局方法 var Tweak = function() { // 这里的Tweak是一个局部变量名,与window.Tweak不相关 this.init(arguments[0]); }; Tweak.prototype = { // 局部变量名 args: arguments, init: function() { console.log(arguments[0]); //firefox [1, 2] //safari: [object Arguments] return this; } } return new Tweak(arguments);}var t = Tweak(1, 2);console.log(t.args); // [1, 2] // [object Arguments] |
第二种是变量名覆写了方法名
var Tweak = Tweak(1, 2); // javascript中的function会先被解析器解析,这里Tweak(1, 2)已经在调用下面的Tweak方法,但此方法调用完成后马上被变量Tweak覆写function Tweak() { var Tweak = function() { // 这里的Tweak是一个局部变量名,与window.Tweak不相关 this.init(arguments[0]); }; Tweak.prototype = { // 局部变量名 args: arguments, init: function() { console.log(arguments[0]); //firefox [1, 2] //safari: [object Arguments] return this; } } return new Tweak(arguments);}// Tweak(1, 2); // 这句代码已经执行错误,因为Tweak已经是一个对象,而不是方法了。 |
第三种是方法名覆写了变量名
var Tweak = {};Tweak = function() { // Tweak 变量被重新赋为一个function对象 var Tweak = function() { // 这里的Tweak是一个局部变量名,与window.Tweak不相关 this.init(arguments[0]); }; Tweak.prototype = { // 局部变量名 args: arguments, init: function() { console.log(arguments[0]); //firefox [1, 2] //safari: [object Arguments] return this; } } return new Tweak(arguments);}Tweak(1, 2); // 这句代码可以执行 |