You Don't Know JS Yet Book 1 Notes


Get Started - 前言

But let me be clear: I don't think it's possible to ever fully know JS. That's not an achievement to be obtained, but a goal to strive after. You don't finish knowing everything about JS, you just keep learning more and more as you spend more time with the language. And the deeper you go, the more you revisit what you knew before, and you re-learn it from that more experienced perspective.

不要抱着“我可以完全了解JS”的心态来学习,这是一个不可实现的目标

All developers regularly struggle with some piece of code not working correctly, and they can't figure out why. But far too often, JS developers will blame this on the language rather than admitting it's their own understanding that is falling short. These books serve as both the question and answer: why did it do this, and here's how to get it to do that instead.

不要把代码不工作归罪与语言本身有缺陷,是你自己不理解你使用的语言是如何(how)工作的

Don't binge these books; be patient and spread out your reading. Interleave reading with lots of practice on real code in your job or on projects you participate in. Wrestle with the opinions I've presented along the way, debate with others, and most of all, disagree with me! Run a study group or book club. Teach mini-workshops at your office. Write blog posts on what you've learned. Speak about these topics at local JS meetups.

不要把这书学死了,争论、记录心得、参加当地的聚会来分享自己的见解都是不错的选择

These books are meant to be a field-guide on your wanderings through JavaScript, from wherever you currently are with the language, to a place of deeper understanding. And the deeper you understand JS, the more questions you will ask and the more you will have to explore! That's what I find so exciting!

了解更多,探索更多

Get Started - Chapter 1: What Is JavaScript?

Further distancing the language from the Oracle-owned trademark, the official name of the language specified by TC39 and formalized by the ECMA standards body is ECMAScript. And indeed, since 2016, the official language name has also been suffixed by the revision year; as of this writing, that's ECMAScript 2019, or otherwise abbreviated ES2019.

自从2016开始,官方就使用"ES+年号"的方式来指代最新的ES版本,所以不要使用ES7或JS7这样的称呼,这只会使得人更加困惑,坚持使用"ES20XX"或者JS来称呼

"Java is to JavaScript as ham is to hamster." --Jeremy Keith, 2009

Java 和 JavaScript 的关系就像雷锋和雷峰塔

The TC39 committee is comprised of between 50 and about 100 different people from a broad section of web-invested companies, such as browser makers (Mozilla, Google, Apple) and device makers (Samsung, etc). All members of the committee are volunteers, though many of them are employees of these companies and so may receive compensation in part for their duties on the committee.

TC39 委员会的成员,有来自浏览器厂商的,也有来自设备厂商的,所有都是志愿者,并且可能会得到一笔津贴

In these cases, often TC39 will backtrack and simply choose to conform the specification to the reality of the web. For example, TC39 planned to add a contains(..) method for Arrays, but it was found that this name conflicted with old JS frameworks still in use on some sites, so they changed the name to a non-conflicting includes(..). The same happened with a comedic/tragic JS community crisis dubbed "smooshgate," where the planned flatten(..) method was eventually renamed flat(..).

一些趣闻,标准的制定并不是空中楼阁式的,会听取显示的声音

Developer Tools are... tools for developers. Their primary purpose is to make life easier for developers. They prioritize DX (Developer Experience). It is not a goal of such tools to accurately and purely reflect all nuances of strict-spec JS behavior. As such, there's many quirks that may act as "gotchas" if you're treating the console as a pure JS environment.

不要认为开发者工具反映了JS实际的运行方式,工具只是工具,是为了优化开发体验的,和JS实际的运行方式有区别

Paradigms are neither right nor wrong. They're orientations that guide and mold how programmers approach problems and solutions, how they structure and maintain their code.

编程的范式没有对错之分,JS 是一个多范式的语言,你可以在行的级别来选择不同的范式,而不用做一个一刀切的决定

backwards compatibility vs forwards compatibility
向后兼容和向前兼容

Code written in 1995—however primitive or limited it may have been!—should still work today. As TC39 members often proclaim, "we don't break the web!"

写在1995年的JS代码,今天仍可工作————向后兼容的例子

Being forwards-compatible means that including a new addition to the language in a program would not cause that program to break if it were run in an older JS engine. JS is not forwards-compatible, despite many wishing such, and even incorrectly believing the myth that it is.

向前兼容意味着,给语言增加了新的特性,其仍然可在较老的JS引擎上运行,JS显然不是向前兼容的语言,HTML和CSS由于指令式的特征,与JS相反,是向前兼容而不是向后兼容的语言,意识到JS是向后兼容的,可以让我们看到它带给Web的好处以及语言自身的限制

正式因为JS不是向前兼容的语言,才有了Babel这样的转译工具存在,不然我们只能写最老的浏览器上支持的写法了

Developers should focus on writing the clean, new syntax forms, and let the tools take care of producing a forwards-compatible version of that code that is suitable to deploy and run on the oldest-supported JS engine environments.

开发者应该专注于写干净的、新式语法的形式,让工具来转译,以使得代码可以运行在最古老的JS引擎上。

如果JS非向前兼容带来的gap不是语法上的,而是API层面的,例如老的JS引擎上缺少这个API,通常的做法就是加入polyfill (aka "shim").

The real reason it matters to have a clear picture on whether JS is interpreted or compiled relates to the nature of how errors are handled.

关于JS是解释型语言还是编译型语言的争论,不要停留在形式上(是否有二进制文件发布),而是要聚焦与错误处理

Get Started - Chapter 2: Surveying JS

It's very common to suggest that var should be avoided in favor of let (or const!), generally because of perceived confusion over how the scoping behavior of var has worked since the beginning of JS. I believe this to be overly restrictive advice and ultimately unhelpful. It's assuming you are unable to learn and use a feature properly in combination with other features. I believe you can and should learn any features available, and use them where appropriate!

任何feature都值得学习,关键看你怎么使用

If you stick to using const only with primitive values, you avoid any confusion of re-assignment (not allowed) vs. mutation (allowed)! That's the safest and best way to use const.

作者关于何时使用 const 的建议

Since the lying about such comparisons can be bothersome, it's best to avoid using === for them. For NaN comparisons, use the Number.isNaN(..) utility, which does not lie. For -0 comparison, use the Object.is(..) utility, which also does not lie. Object.is(..) can also be used for non-lying NaN checks, if you prefer. Humorously, you could think of Object.is(..) as the "quadruple-equals" ====, the really-really-strict comparison!

=== 从最严格的意义上来说,并不严格,例如比较两个 NaN 或者 -0 和 0

The == operator performs an equality comparison similarly to how the === performs it. In fact, both operators consider the type of the values being compared. And if the comparison is between the same value type, both == and === do exactly the same thing, no difference whatsoever.

与广为流传的“在比较时不考虑类型”相反,“” 和 “=”在比较两个值的时候都会考虑类型,如果类型相同,“”和“===”做的其实一模一样

Get Started - Chapter 3: Digging to the Roots of JS

Closure is when a function remembers and continues to access variables from outside its scope, even when the function is executed in a different scope.

对闭包的精确定义,一个函数即使在不同的作用域中执行,仍可访问自身作用域外的变量

Scope is static and contains a fixed set of variables available at the moment and location you define a function, but a function's execution context is dynamic, entirely dependent on how it is called (regardless of where it is defined or even called from).

作用域(scope)和执行上下文(execution context)是不同的概念,作用域是静态的,在你定义函数的位置包含了一个固定的可访问变量的集合,但是一个函数的执行上下文是动态的,完全取决于函数式如何被调用的(和它是何处定义或从何处调用的无关)

One way to think about the execution context is that it's a tangible object whose properties are made available to a function while it executes. Compare that to scope, which can also be thought of as an object; except, the scope object is hidden inside the JS engine, it's always the same for that function, and its properties take the form of identifier variables available inside the function.

一个方式是把执行上下文设想成一个可感知的对象,它的属性是当函数执行的时候可以访问。对比作用域,作用域也可以被设想成对象,作用域对象隐藏于JS引擎中,对于函数来说总是一样的,并且它将属性以函数内可用的变量的形式暴露出来。

The benefit of this-aware functions—and their dynamic context—is the ability to more flexibly re-use a single function with data from different objects. A function that closes over a scope can never reference a different scope or set of variables. But a function that has dynamic this context awareness can be quite helpful for certain tasks.

动态的上下文的存在,使得单个函数可以使用来自不同的对象的数据(在执行某些特定任务的时候可能很有用),一个函数的作用域则不能动态指定

As you are getting started learning and knowing JS more closely, one of the most important skills you can practice and bolster is curiosity, and the art of asking "Why?" when you encounter something in the language.

待着好奇心,学会提问

You'll have to shift these things little by little, over time. Work on building consensus with your fellow developers on why it's important to re-visit and re-consider an approach. But do so with just one small topic at a time, and let before-and-after code comparisons do most of the talking. Bring everyone on the team together to discuss, and push for decisions that are based on analysis and evidence from the code rather than the inertia of "our senior devs have always done it this way."

保持批判性

There's no better way to learn code than to write it.

没有比写代码更好的学编程语言的方式了

If a function has a name, you the code author should include that name in the code, so that the reader does not have to infer that name from reading and mentally executing that function's source code. Even a trivial function body like x * 2 has to be read to infer a name like "double" or "multBy2"; that brief extra mental work is unnecessary when you could just take a second to name the function "double" or "multBy2" once, saving the reader that repeated mental work every time it's read in the future.

如果一个函数有名称,你作为代码的作者就应该在代码里包含,这样读者就不用从阅读和在脑海里执行函数来推测那个名称,即使是很小的函数体例如 x * 2 也需要被推测出姓名,例如 "bouble" 或者 "multBy2"; 这些额外的精神工作是不必要的,尤其是当你可以花费几秒钟的时间来给函数命名,给读者节约了许多未来的精神上的开销

All functions by default reference an empty object at a property named prototype. Despite the confusing naming, this is not the function's prototype (where the function is prototype linked to), but rather the prototype object to link to when other objects are created by calling the function with new.

所有的函数都默认地通过自己的 prototype 属性指向一个空对象,这个名字令人困惑,这不是函数自己的原型,而是当函数被当做构造函数调用时(new)创建出的对象的原型

This "prototypal class" pattern is now strongly discouraged, in favor of using ES6's class mechanism:

这种“原型类”的模式现在被强烈地不建议使用,使用ES6的class语法可以更清晰的表达面向类的模式

相关