我一直在看Sharepoint脚本文件,但是我遇到过这个问题:
function ULSTYE() {
var o = new Object;
o.ULSTeamName = "Microsoft SharePoint Foundation";
o.ULSFileName = "SP.UI.Dialog.debug.js";
return o;
}
SP.UI.$create_DialogOptions = function() {
ULSTYE:; <----------------------------- WTF?
return new SP.UI.DialogOptions();
}
实际上,此文件中的每个函数定义都在开始括号后面的相同ULSTYE:;
行开头。任何人都可以解释第二个函数的第一行是做什么的吗?
Firefox / Firebug例如将此函数解释为我无法理解的东西:
function () {
ULSTYE: {
}
return new (SP.UI.DialogOptions);
}
我以为我一直都知道Javascript ...... ;)必须是我过去从未使用的一些模糊的功能,显然很少被其他人使用。
答案 0 :(得分:21)
在对这个问题进行了长时间的思考之后,我终于坐下来解决了这个问题。它是在客户端收集诊断信息的相对复杂机制的一部分,包括将javascript callstack(包括函数名和javascript文件)发送回服务器的能力。
查看位于
的文件init.debug.js的前250行%Program Files%\ Common Files \ Microsoft Shared \ Web Server Extensions \ 14 \ TEMPLATE \ LAYOUTS \ 1033 \ init.debug.js
此文件定义了客户端上“ULS”实现的所有功能。
当然,您需要安装SharePoint 2010才能使文件存在于本地计算机上。
更新 - 以下概述了该机制的工作原理。真正的实现不仅仅是这个
考虑以下带有几个js包含的html页面,每个页面都可以相互调用。
<html>
<head>
<script type="text/javascript" src="ErrorHandling.js"></script>
<script type="text/javascript" src="File1.js"></script>
<script type="text/javascript" src="File2.js"></script>
</head>
<body>
<button onclick="DoStuff()">Do stuff</button>
</body>
</html>
我们有两个js包含文件,File1.js
function ULSabc() { var o = new Object; o.File = "File1.js"; return o; }
/* ULSabc is the unique label for this js file. Each function in
this file can be decorated with a label corresponding with the same name */
function DoStuff() {
ULSabc: ;
//label matches name of function above
DoMoreStuff();
}
和File2.js
function ULSdef() { var o = new Object; o.File = "File2.js"; return o; }
function DoMoreStuff() {
ULSdef: ;
DoEvenMoreStuff();
}
function DoEvenMoreStuff() {
ULSdef: ;
try {
//throw an error
throw "Testing";
} catch (e) {
//handle the error by displaying the callstack
DisplayCallStack(e);
}
}
现在,我们的ErrorHandling文件看起来像这样
function GetFunctionInfo(fn) {
var info = "";
if (fn) {
//if we have a function, convert it to a string
var fnTxt = fn.toString();
//find the name of the function by removing the 'function' and ()
var fnName = fnTxt.substring(0, fnTxt.indexOf("(")).substring(8);
info += "Function: " + fnName;
//next use a regular expression to find a match for 'ULS???:'
//which is the label within the function
var match = fnTxt.match(/ULS[^\s;]*:/);
if (match) {
var ULSLabel = match[0];
//if our function definition contains a label, strip off the
// : and add () to make it into a function we can call eval on
ULSLabel = ULSLabel.substring(0, ULSLabel.length - 1) + "()";
//eval our function that is defined at the top of our js file
var fileInfo = eval(ULSLabel);
if (fileInfo && fileInfo.File) {
//add the .File property of the returned object to the info
info += " => Script file: " + fileInfo.File;
}
}
}
return info;
}
function DisplayCallStack(e) {
//first get a reference to the function that call this
var caller = DisplayCallStack.caller;
var stack = "Error! " + e + "\r\n";
//recursively loop through the caller of each function,
//collecting the function name and script file as we go
while (caller) {
stack += GetFunctionInfo(caller) + "\r\n";
caller = caller.caller;
}
//alert the callstack, but we could alternately do something
//else like send the info to the server via XmlHttp.
alert(stack);
}
当我们点击页面上的按钮时,我们的脚本文件将调用每个函数并以DisplayCallStack结束,此时它将递归循环并收集堆栈跟踪
Error! Testing
Function: DoEvenMoreStuff => Script file: File2.js
Function: DoMoreStuff => Script file: File2.js
Function: DoStuff => Script file: File1.js
Function: onclick
答案 1 :(得分:14)
第一位定义了一个函数,该函数创建一个具有几个属性的对象并返回它。我想我们都清楚这一点。 : - )
然而,第二位是不使用该功能。它定义了一个名称相同的标签。虽然它使用相同的字符序列,但不是对上述函数的引用。 Firefox的解释与其他任何东西一样有意义,因为标签后面应该跟一些它可以引用的内容。
有关标签语句的更多信息,请参阅the spec的第12.12节。
偏离主题:我会避免使用此来源的代码。编写它的人显然对JavaScript很新,并没有表明他们知道自己在做什么。例如,他们已将()
从new Object()
电话中移开,虽然这是允许的,但这样做是相当狡猾的事情。他们可以争辩说他们这样做是为了节省空间,但如果他们这样做,他们最好不要使用对象文字:
function ULSTYE() {
return {
ULSTeamName: "Microsoft SharePoint Foundation",
ULSFileName: "SP.UI.Dialog.debug.js"
};
}
根本没有太多理由写new Object()
; {}
在功能上完全相同。
当然,第二位根本就没有理由。 : - )
答案 2 :(得分:4)
不仅仅是statement label吗?我认为标签与早期函数同名的事实并不意味着什么。
答案 3 :(得分:0)