如何在JavaScript中为函数构造函数使用作用域?
如果我要使用如何在JavaScript中为函数构造函数使用作用域?,javascript,function,scope,Javascript,Function,Scope,如果我要使用函数构造函数创建一个新的函数,除了窗口之外,我如何给它一个非临时的访问范围(这意味着该范围只需评估一次,而不是每次调用该函数)?其目的是构造多个变量,这些变量需要一些非常昂贵的计算,我不想每次调用函数时都重新构造它们,但我也不想将它们存储在窗口中。有什么想法吗?出于上述目的,您可以使用静态函数。您不能阻止在每次调用时对作用域进行求值,因为这是JavaScript的工作方式,但您可以通过在作用域链中不使用window来加快计算速度 var namespace = {}; namespa
函数
构造函数创建一个新的函数
,除了窗口
之外,我如何给它一个非临时的访问范围(这意味着该范围只需评估一次,而不是每次调用该函数)?其目的是构造多个变量,这些变量需要一些非常昂贵的计算,我不想每次调用函数时都重新构造它们,但我也不想将它们存储在窗口中。有什么想法吗?出于上述目的,您可以使用静态函数。您不能阻止在每次调用时对作用域进行求值,因为这是JavaScript的工作方式,但您可以通过在作用域链中不使用window
来加快计算速度
var namespace = {};
namespace.someMethod = function() {
// do something here.
};
现在,在代码中的任何地方,都可以使用namespace.someMethod()调用该方法代码>。小心点。以上是一种静态方法。您可以调用它而无需实例化。但是不能在静态函数中使用此.property
。这是一个潜在的非常危险的操作,因为它可能会授予对全局对象的扩展访问权限以及基本上不受限制的权限
上面是一个静态JavaScript方法。它在作用域链中没有窗口
var namespace = {};
namespace.someMethod = function() {
// do something here.
};
下面介绍如何使用相同的模式创建构造函数。当您想要使用构造函数时,您总是在使用之前进行实例化。为此,您有new
关键字
var namespace = {};
namespace.coordinate = function(x, y) {
this.x = x;
this.y = y;
};
namespace.coordinate.prototype.addCoordinates = function() {
return this.x + this.y;
};
现在,您可以在代码中的任何位置执行以下操作:
var coordinateObject = new namespace.coordinate(5,10);
// you have created a new instance.
alert(coordinateObject.addCoordinates());// will alert 15;
// now you can make as many as you want. They will behave as instances.
// This means they do not interfere with each other in any way.
// They just have the same properties and methods, but the instance values
// Can be entirely different.
var secondCoordinateObject = new namespace.coordinate(10, 25);
alert(secondCoordinateObject.addCoordinates());// will output 35.
您已经成功地创建了名称空间.coordinate
类的实例。使用我提供的模式,您可以复制Java或C或任何其他面向对象语言的几乎全部功能。您可以使用bind
关键字将函数绑定到特定上下文:
var context = {};
var f = new Function("args", "return this").bind(context);
f(); // context
由于绑定是在ECMA 5th中定义的,它可能不会出现在所有浏览器中,不断增长的创建、存储、隐藏、显示和分组变量和函数的方法是通过“闭包”的魔力实现的,这是Javascript最强大但尚未实现的功能:
var groupObj = (function (setUp) {
// maintained by reference, hidden
var _priVar = setUp * 2;
// maintained by reference, revealed (through returned object)
var _pubVar = 8;
var _pubFunc = function (x) {
_priVar += x;
_pubVar += x;
}
var lostVar = setUp * 99; // not referenced, hidden, so evaporates!
return {
'pubVar' : _pubVar,
'pubFunc' : _pubFunc
}
}(4)); // runs immediately with 4 as setUp, revealing pubVar & pubFunc
然后
groupObj.pubFunc(7); // runs public function, adds 7 to both variables
alert('public variable: ' + groupObj.pubVar); // alerts public variable
每当在另一个函数中有一个函数时,就会发生闭包。只要outter函数中的变量被内部函数引用,它就会被维护,这是一种“无人地带”,在这种情况下,一个变量通过从较低范围对它的引用而被迫存在,但由于Javascript的固有原理,它被隐藏在较高范围之外
使用闭包、替换对象构造函数、一次性无冲突私有函数等还有一些其他方法。这里有很多关于他们的帖子
var yourNamespace = {
func1: function() {
},
func2: function() {
}
};
...
yourNamespace.func1();
您可以通过从名称空间调用函数来调用所需的函数,如yourNamespace.func1() 因此,我将变量存储到名称空间
,并通过函数中的this[varName]
引用它们?我不能使用静态函数,因为我正在为复杂的数学表达式编写JavaScript编译器。哦!我可以执行someMethod.call(名称空间,arg0,arg1,…argN)
。我想那会很有效的!问题是,这个函数是为了一个特定的目的,并且只会因为一个原因被调用,所以另一个答案对于我正在做的事情来说是完美的。好的,我可以理解为什么这可能会更好。。。但我的问题是,名称空间
对于实现这一点是否有必要?或者如果坐标
对象未附加坐标
,则坐标
和坐标.prototype.addCoordinates
的工作方式会有所不同吗?构造函数将位于匿名函数中,因此我猜它不会干扰任何其他内容。这甚至比函数.prototype.call
更好!非常感谢。谢谢,但事实上,我的程序需要HTML5才能工作,因此如果浏览器不支持HTML5,解决方法将毫无意义。bind()
设置此
,而不是全局范围。