Javascript - 揭示对象和变量范围
Javascript - revealing object and variable scope
http://jsfiddle.net/ZLH7J/1/
下面的jsFiddle和代码显示的是两个本质上做同样事情的例子。尝试调用任一示例中的first();
或this.first();
时,都会引发未定义的错误。我可以稍后通过实例调用函数,但在尝试使用构造函数等init(){...}()
实例化对象时则不行。我把 init() 放在底部,认为这是一个操作顺序,但事实并非如此。这不符合我想象的方式。
我很想知道应该如何做到这一点,以及为什么不能这样做。
//create and return an obj
var fishSticks = function(){
return {
first: function(){
document.getElementById('output').innerHTML="Success";
},
init: function(){
try{
first(); //err
this.first(); // also err
}catch(e){
document.getElementById('output').innerHTML=e.toString();
}
}()
}
}
//do function stuff and then return 'this'
var fishFillet = function(){
var first = function(){
document.getElementById('output2').innerHTML="Success";
}
var init = function(){
try{
first(); //err
this.first(); // also err
}catch(e){
document.getElementById('output2').innerHTML=e.toString();
}
}()
return this;
}
var test = new fishSticks();
var test2 = new fishFillet();
你需要了解两件事:
1)JavaScript不会像Java那样自动插入this
,所以first()
调用只会在词法范围内查找first
的定义,它会nok查看this
对象。因此,对first()
的调用应该有效,但this
将绑定到与您在first
中可能期望的其他内容不同的内容。
2) 构造函数中的局部变量不会成为构造对象的成员。
在第二个示例中,如果您注释掉"init"中的调用以this.first()
则会收到"成功"消息。
第一个版本不起作用,因为 JavaScript 根本不允许在构造不足的对象中引用对象本身。 只是没有办法。
第二个有效(对"first"的简单引用有效),因为"first"被声明为局部变量。局部变量不是任何对象的属性,特别是它们不是使用 new
调用函数时分配的对象的属性。 这就是this.first()
不起作用的原因。
在第二个中,您可以通过以不同的方式声明事物来使this.first()
工作:
var fishFillet = function(){
this.first = function(){
document.getElementById('output2').innerHTML="Success";
}
var init = function(){
try{
this.first(); //will work
}catch(e){
document.getElementById('output2').innerHTML=e.toString();
}
}()
return this;
}
此外,对于它的价值,奇怪的反模式
var something = function() { ... }
不如
function something() { ... }
没有理由使用 var
声明而不是 function
声明。
怎么样...
var fishFillet = function () {
var first = function () {
document.write( 'Success' );
};
var init = function () {
first();
};
init();
return {
first: first
};
};
然后:
var ff = fishFillet(); // calls init() which calls first()
ff.first(); // call first() manually
现场演示:http://jsfiddle.net/uaCnv/
因此,首先定义所有函数,然后手动调用init
,最后返回一个对象,其中包含那些应该通过结果对象可用的函数(作为方法)。
由于您将两者用作构造函数,因此请按以下格式设置它们:
function fishFillet(){
this.first = function(){
document.getElementById('output2').innerHTML="Success";
}
this.init = function(){
try{
this.first();
}catch(e){
document.getElementById('output2').innerHTML=e.toString();
}
}
}
var food = new fishFillet();
food.init();
它不适合您的原因是 b/c"first"被创建为本地变量,并在执行后被删除。在构造函数的执行完成之前不会调用 Init
- js命名空间和变量范围
- 如何确保变量范围在这个循环中得到维护
- 在两个浏览器选项卡之间共享变量范围
- 文件API中的Javascript变量范围
- javascript和jQuery的嵌套对象函数中的变量范围
- JavaScript 函数变量范围问题
- JavaScript 中变量范围的问题
- Javascript - 揭示对象和变量范围
- 主干.js(具有 Require.js)变量/范围访问问题
- Javascript 变量范围未定义
- 如何绕过javascript变量范围
- IE 8变量范围错误
- 了解 Javascript 变量范围
- 控制变量范围
- 函数之间的Javascript变量范围问题
- 这种减少if语句中声明的变量范围的模式是一种好的做法吗
- 用于未初始化的局部变量的javascript变量范围
- 变量范围
- 请求节点模块变量范围
- Javascript 和 JQuery dom 全局变量范围