我正在尝试更多地了解Javascript,我已经使用PHP编写代码并制作Web应用程序多年了,我已经掌握了JS的基本知识,我使用过的大部分JS已经编码了,我只是插入它直到最近,在过去的几年里,我已经能够用jQuery做很多事情了。
我注意到Stack Overflow使用的jQuery比我见过的大多数网站都多,它们在这里的所有JS功能都很漂亮。
所以一个基本的问题,Stack Overflow在我在这里看到的大多数JS代码前都使用了StackExchange
。到底是做什么的?对我来说,我想说它就像一个类名,但我读JS没有类。
这是一个示例代码
StackExchange.debug.log("no cache breaker for " + q);
你能否解释一下我解释StackExchange
,debug
,log
是什么?
我的意思是我可以告诉log
必须是函数调用而其他函数是什么?
PS)请不要将其移动到META,因为它是一个JS问题而不是特定于StackOverflow 如果您能想到更好的标题,也可以随意编辑问题标题并删除此行,谢谢
答案 0 :(得分:6)
将StackExchange
想象成全局jQuery函数,“$”(或“jQuery”)。它只是对具有函数和其他属性的对象的全局引用。
因此,“debug”是全局“StackExchange”对象的属性,而“log”又是“debug”对象的属性。在这种情况下,“log”属性引用一个函数,它显然是一个调试工具。
JavaScript是否具有“类”是一个值得商榷的问题,但它肯定有对象。 (通过“有争议的”我的意思是它是一个充满博客帖子和Stackoverflow问题的主题: - )
实际上,就是基本的JavaScript。对此没有任何超级幻想或狡猾。答案 1 :(得分:3)
答案 2 :(得分:2)
EDITED FOR CLARIFICATION
在我说任何事之前,请参阅How Classical Object-Oriented Programming Translates to Javascript。理解这一点非常重要。现在,话虽如此,我会继续:)
Javascript有一个令人遗憾的特点,你必须非常好地理解运行时环境,以便理解为什么某些语法被选择而另一个表达相同的东西(在理论上)。 javascript运行时环境的一个主要注意事项是,无意中将内容放入全局空间非常容易。这是两个快速示例(这些示例假设您没有编写任何其他代码):
/*
* Example 1
* This example uses 'object literal notation'.
* A link to an article about this is below the example.
* This example shows how easy it is to get into the global space just by
* not declaring variables properly.
*/
var myObj = {
myMethod: function() {
test = 'test'; // oops! now the variable test is in the global
// function space :(
// to avoid this, use var test = 'test'; to keep
// test in the scope of myMethod
}
};
/*
* Example 2
* This example shows how the infamous 'this' can be misused to accidentally
* get into the global space.
*/
var myConstructor = function() {
this.test = 'test';
};
var myObj1 = new myConstructor(); // 'this' will by 'myObj1'
var myObj2 = myConstructor(); // 'this' will by the global object :(
要了解示例2为何成立,请参阅this。
避免所有这些令人头疼的方法之一是遵循控制对全局范围的访问的良好模式。正如一些答案所指出的那样,您可以将StackExchange
对象视为用于命名空间目的,但实际上,它最常用于避免上面示例中列出的问题,以及防止作为名称悬挂。此外,如果你聪明地使用闭包范围(利用javascript中的所有作用域都绑定到函数,并且在函数中运行),你可以使这个'命名空间'对象的行为更像是来自其他经典OOP语言的传统对象。 javascript是一流的数据对象)。此外,由于全球空间非常危险,因此最好“成为一名优秀的DOM公民”,并且只在全局空间中创建一个封装所有逻辑和数据的对象。
Joel和jeff实际上可能正在设置闭包范围来执行隐藏javascript方式的信息。以下只是一个例子:
StackExchange = (function() { // give StackExchange it's own scope to prevent
// name hoisting and also to allow for private
// data
var version = '1.0.0'; // version only seen inside function scope
return { // return an object that will become 'StackExchange' and whose
// methods have access to this function's scope (closure)
debug: (function() {
// set up logging function that will be determined based on
// 'someCondition' (not defined in this code)
var loggingFn = (someCondition) : console.log ? alert;
return { // return obj with access to this function scope
log: function(strToLog) {
loggingFn.call(this, strToLog);
}
};
})(), // immediately execute to make object with 'debug' scope access
getVersion: function() {
return version; // this function has access to StackExchange
// scope; therefore, version will be available
}
};
})(); // immediately execute to make object with 'StackExchange' scope access
有关详细信息,请参阅name hoisting和scoping。另外,请阅读Prototypical Inheritance in Javascript以了解用于避免全局范围问题的模式。
答案 3 :(得分:1)
此代码将定义执行示例中显示的调用所需的对象。如您所见,它只是定义了一个包含更多对象的对象,最终包含一个或多个函数。
var StackExchange = {
debug: {
log: function(whatever) { /* some code */ }
}
};
StackExchange.debug.log("no cache breaker for " + q);
答案 4 :(得分:1)
StackExchange是一个全局对象,debug是另一个对象,它是StackExchange对象的一个属性,它有一个名为log的函数。
详细了解JavaScript here中的对象。