Javascript 中的高级构造
我在 github 上发现了一个有趣的项目,该项目处理 pdf 渲染浏览器。
我尝试阅读代码,因为我对这个主题感兴趣,但我意识到我的 javascript 知识很差(不足)。
有这样的结构:
var Obj = (function() {
function constructor(type, value) {
this.type = type;
this.value = value;
}
constructor.prototype = {
};
var types = [
"Bool", "Int", "Real", "String", "Name", "Null",
"Array", "Dict", "Stream", "Ref",
"Cmd", "Error", "EOF", "None"
];
for (var i = 0; i < types.length; ++i) {
var typeName = types[i];
constructor[typeName] = i;
constructor.prototype["is" + typeName] =
(function (value) {
return this.type == i &&
(typeof value == "undefined" || value == this.value);
});
}
constructor.prototype.lookup = function(key) {
function lookup(key) {
if (!(this.value.contains(key)))
return Obj.nullObj;
return this.value.get(key);
}
}
Object.freeze(constructor.trueObj = new constructor(constructor.Bool, true));
Object.freeze(constructor.falseObj = new constructor(constructor.Bool, false));
Object.freeze(constructor.nullObj = new constructor(constructor.Null));
Object.freeze(constructor.errorObj = new constructor(constructor.Error));
Object.freeze(constructor.prototype);
Object.freeze(constructor);
return constructor;
})();
您可以在上面的链接中看到更多。
您能否建议我一些学习资源,以便能够轻松理解项目中的代码,甚至更好地为项目做出贡献?
I found one interesting project on github which deals with pdf rendering in the browser.
I tried to read the code because I'm interested in this topic but I realized that my javascript knowledge is poor (insuficient).
There are constructs like:
var Obj = (function() {
function constructor(type, value) {
this.type = type;
this.value = value;
}
constructor.prototype = {
};
var types = [
"Bool", "Int", "Real", "String", "Name", "Null",
"Array", "Dict", "Stream", "Ref",
"Cmd", "Error", "EOF", "None"
];
for (var i = 0; i < types.length; ++i) {
var typeName = types[i];
constructor[typeName] = i;
constructor.prototype["is" + typeName] =
(function (value) {
return this.type == i &&
(typeof value == "undefined" || value == this.value);
});
}
constructor.prototype.lookup = function(key) {
function lookup(key) {
if (!(this.value.contains(key)))
return Obj.nullObj;
return this.value.get(key);
}
}
Object.freeze(constructor.trueObj = new constructor(constructor.Bool, true));
Object.freeze(constructor.falseObj = new constructor(constructor.Bool, false));
Object.freeze(constructor.nullObj = new constructor(constructor.Null));
Object.freeze(constructor.errorObj = new constructor(constructor.Error));
Object.freeze(constructor.prototype);
Object.freeze(constructor);
return constructor;
})();
You can see more of them in the link above.
Could you please advise me some resources which to study to be able to understand the code in the project with ease and even better to contribute later to the project?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从外到内工作,这里的第一个大概念是匿名函数。
简单来说,我们正在创建一个匿名函数,然后立即执行它,
并将匿名函数的返回值分配给名为 Obj 的变量。
为什么有人想要这样做?
在本例中,它用于创建私有范围。 javascript中的局部变量是
作用域为定义它们的函数。例如:
在最后一个例子中,
a
实际上只存在于函数的作用域内定义了它。 Javascript 在这方面有点棘手,因为省略了
var
关键字,可以定义全局变量。
所以在你给出的例子中,他们使用这个匿名函数来构建一个
一些将被使用但最终会被抛出的变量的作用域
函数执行完毕后立即消失。
接下来:
这将创建一个名为
constructor
的新函数。需要注意的是 javascript 函数是一流对象,这意味着它们的工作方式与任何其他对象非常相似,并且可以被指派
到一个变量。该函数的作用域为匿名函数。所以试图让
constructor
出来超出了其功能范围,不起作用。例如
,到目前为止,如果您要执行到目前为止的代码片段,那么
Obj
将是未定义的。现在让我们跳到最后,看看返回结果。
因此,当调用匿名函数时,它会返回构造函数。这个函数得到
传回的值被分配给
Obj
。这将构造函数交回,超出了本地范围函数,并赋值给变量。然后您就可以调用它
接下来我们有一个有趣的行
这将构造函数的原型设置为空对象。解释原型的细节是
这篇文章的一部分范围,但过于简单的是原型定义了实例方法
可用于由构造函数创建的对象。之间共享一个“原型”
并将用于定义可用于构造的对象的方法
调用
new Obj()
。接下来,我们有一个本地定义的数组,
请记住,因为我们位于函数内部,所以该变量绑定在外部匿名函数的作用域内。
接下来我们循环遍历该数组,并设置一些东西。
这里发生了两件有趣的事情。首先,它在构造函数中设置一个“静态”属性,然后
在构造函数的原型上创建一个新函数。该函数称为
“is”+ typeName
。所以我们应该生成一堆名为“isBool”、“isInt”、“isReal”等的实例方法。
接下来,我们定义另一个名为
lookup
的实例方法并执行一些工作。最后,我们从构造函数中创建一些静态属性,并冻结它们(这样它们就不能被更改或扩展)
一旦一切都说完了,Obj 应该指向一个构造函数,我们应该能够这样说:
无论如何,我希望这有助于解释一些正在使用的概念。最重要的收获应该是
函数可以用来控制范围,并且函数是一级函数,并且可以传递
就像变量一样。您还可以使用点符号 (
obj.property
) 或方括号符号引用对象的属性(
obj["属性"]
)。还有很多东西需要学习,所有的书籍建议都在这个线程中。如果没有提到我
还会推荐 Haverbeke 的 Eloquent JavaSript。
Working outside in, the first big concept here are anonymous funcitons.
Simply, put, we are making an anonymous function, and then immediately execturing it,
and assigning the return from the anonymous function to an variable named Obj.
Why would anyone want to do it?
In this case, it is used to create a private scope. Local variables in javascript are
scoped to the function where they are defined. For example:
In the last example,
a
really only exists inside the scope of the function thatdefined it. Javascript is a little tricky this regard because by omitting the
var
keyword, you can define a global variable.
So in the example you've given, they are using this anonymous function to build a
scope for some variables that will be used, but will ultimately want to be thrown
away as soon as the function is finished executing.
Next:
This creates a new function called
constructor
. Its important to note that javascript functionsare first-class objects, which means they work a lot like any other object, and can be assigned
to a variable. This function is scoped to the anonymous function. So trying to get
constructor
outside of the scope of its function, doesn't work. For example
So far, if you were to execute the snippits so far, then
Obj
would have been undefined. Nowlet's skip ahead a bit to end, and look at the return.
So when the anonymous function gets invoked, it returns the constructor. This function that gets
passed back is assigned to
Obj
. This hands back the constructor, out of the local scope of thefunction, and assigns to the variable. You would then be able to invoke it
Next we've got an interesting line
This sets the prototype for the constructor to an empty object. Explaining the details of prototypes is
a bit of the scope of this post, but an over-simplication is that a prototype defines the instance methods
that are available to an object that is created by a constructor. A single 'prototype' is shared between
and will be used to define the methods that will be available to the objects that are constructed by
calling
new Obj()
.Next we have a locally defined array
Remember because we are inside of a function, this variable is bound within the outer anonymous function's scope.
Next we loop through that array, and set up some stuff.
Two things interesting happen here. First, it sets a 'static' property off of the
constructor
, and thencreates a new function on the constructor's prototype. This function is called
"is" + typeName
. So we shouldgenerate a bunch of instance methods named stuff like: "isBool", "isInt", "isReal", and so on.
Next we define another instance method called
lookup
and does some work.Lastly we create some static properties off of our constructor, and freeze them (so they can't be changed or extended)
Once its all said and done,
Obj
, should point to a constructor function, and we should be able to say things like:Anyway, I hope that helped a little bit explaining a few of the concepts that were being used. The big take-away should
be that a
function
can be used to control scope, and that functions are First-class functions, and can be handed aroundlike variables. You can also reference a property off a object using dot notation (
obj.property
) or bracket notation(
obj["property"]
).There are a bunch of more things to learn, and all of the book suggestions are solid in this thread. If it hasn't been mentioned I
would also recommend Eloquent JavaSript by Haverbeke.
Douglas Crockford 的书 JavaScript: The Good Parts 是这是一个了解 JavaScript 强大功能的好地方,同时引导您远离丑陋(或完全危险)的部分。 他的网站还收集了有关该语言的有趣文章。我推荐两者。
Douglas Crockford's book JavaScript: The Good Parts is a great place to gain an appreciation of the power in JavaScript, while steering you away from the ugly (or downright dangerous) parts. His website also has a collection of interesting articles about the language. I recommend both.
也许其中一些链接会对您有所帮助:
https://developer.mozilla.org/en /Core_JavaScript_1.5_Guide/Details_of_the_Object_Model,
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript,
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Objects ,
https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited ,
Maybe some of these links will help you out:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Details_of_the_Object_Model,
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript,
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Objects,
https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited,
我可以参考一些链接
我可以命名吗一个 JavaScript 函数并立即执行它?
http:// devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
我希望你可以和他们一起学习
I can refer some links
Can I name a javascript function and execute it immediately?
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
I hope you can learn with them
我找到了 Douglas Crockford(http://www.crockford.com/)、John Resig(< a href="http://ejohn.org/blog/" rel="nofollow">http://ejohn.org/blog/) 对于中级到高级概念很有用。查看其他人的代码(就像您正在做的一样)也会有所帮助。归根结底,没有什么比实际尝试这个概念更好的了,为此值得信赖的 Firebug 控制台仍然是最好的。
I find the blogs by Douglas Crockford(http://www.crockford.com/), John Resig(http://ejohn.org/blog/) useful for intermediate to advanced concepts. Looking at other people's code(just like what you are doing) can also be helpful. At the end of the day though nothing beats actually trying out the concept and for that the trusty Firebug console is still the best.