java开发人员_避免成为Java开发人员的十种做法

java开发人员

Many of JavaScript’s subtleties lead to a number of common mistakes that keep it from working — 10 of which we discuss here — that are significant to be aware of and avoid in one’s journey to become a master JavaScript developer. Let’s get started!

JavaScript的许多微妙之处导致了许多常见错误,这些错误使它无法正常工作(我们在这里讨论了其中的10个),这对于意识到并避免成为JavaScript高手的过程非常重要。 让我们开始吧!

Stay safe: Learn about Covid-19 on Fox News Live Stream.

保持安全:在Fox News Live Stream上了解Covid-19

我们将讨论的要点: (Points that we’ll discuss:)

1) Incorrect references to this2) Thinking there is a block-level scope3) Creating memory leaks4) Confusion regarding equality5) Inefficient DOM manipulation6) Incorrect use of function definitions inside for loops7) Failure to appropriately leverage prototypal inheritance8) Creating incorrect references to instance methods9) Providing a string as the initial argument to setTimeout or setInterval10) Failure to use “strict mode”

1)对此的错误引用2)认为存在块级范围3)创建内存泄漏4)关于平等的困惑5) DOM操作效率低下6)在循环内部错误使用函数定义7)无法适当利用原型继承8 )创建对实例方法的不正确引用9)提供字符串作为setTimeout或setInterval的初始参数10)无法使用“严格模式”

1)不正确的引用 (1) Incorrect references to this)

For developers, there often exists confusion regarding JavaScript’s this Keyword. I mean, is this really this, or is it something else completely? Or is it undefined?

对于开发人员来说,关于JavaScript的this关键字经常会感到困惑。 我的意思是, this是真的吗,还是其他的东西? 还是未定义?

As JavaScript coding procedures and design patterns have become increasingly sophisticated over time, there’s been a corresponding climb in the proliferation of self-referencing scopes within callbacks and closures, which are a pretty common source of “this/that confusion.”

随着JavaScript编码过程和设计模式随着时间的推移变得越来越复杂,回调和闭包内自引用范围的泛滥也相应地攀升,这是“此/该混乱”的常见原因。

Take a look at this example code snippet:

看一下这个示例代码片段:

Game.prototype.restart = function () {
this.clearLocalStorage();
this.timer = setTimeout(function() {
this.clearBoard(); // what is “this”?
}, 0);
};

Executing the above code gives the following error:

执行上面的代码将产生以下错误:

Uncaught TypeError: undefined is not a function

Why?

为什么?

It’s all about the context. The reason you experience the above error is that when you invoke setTimeout(), you’re actually invoking window.setTimeout(). Consequently, the anonymous function being passed to setTimeout() is being defined in the context of the window object, which carries no clearBoard() method.A customary, old-browser-compliant solution is to simply save your reference to this in a variable that can then be inherited by the closure: e.g.:

这都是关于上下文的。 遇到上述错误的原因是,当您调用setTimeout() ,实际上是在调用window.setTimeout() 。 因此,传递给setTimeout()的匿名函数是在window对象的上下文中定义的,该对象不clearBoard() 。常规的,与旧浏览器兼容的解决方案是简单地将this的引用保存在变量中然后可以由闭包继承:例如:

Game.prototype.restart = function () {
this.clearLocalStorage();
var self = this; // save reference to ‘this’, while it’s still this!
this.timer = setTimeout(function(){
self.clearBoard(); // oh OK, I do know who ‘self’ is!
}, 0);
};

Alternatively, in a modern browser, you can use the bind() method to pass in the appropriate reference:

另外,在现代浏览器中,您可以使用bind()方法来传递适当的引用:

Game.prototype.restart = function () {
this.clearLocalStorage();
this.timer = setTimeout(this.reset.bind(this), 0); // bind to ‘this’
};Game.prototype.reset = function(){
this.clearBoard(); // ahhh, back in the context of the right ‘this’!
};

2)认为存在块级范围 (2) Thinking there is a block-level scope)

One more source of confusion among JavaScript developers is assuming that JavaScript creates a new scope for each code block. Although this is right for many other languages, it’s not true in JavaScript.

JavaScript开发人员中的另一个困惑源是,假定JavaScript为每个代码块创建一个新的作用域。 尽管这适用于许多其他语言,但在JavaScript中却并非如此。

Consider looking at the following code:

考虑查看以下代码:

for (var i = 0; i < 10; i++) {
/* … */
}
console.log(i); // what will this output?

If you think that the console.log() all would like either output undefined or throw an error, you guessed inaccurately. Believe it or not, it will output 10. Why?

如果您认为console.log()都希望输出undefined或抛出错误,那么您可能会猜错。 信不信由你,它会输出10 。 为什么?

In most other languages, the code above would give an error because the “life” (i.e., scope) of the variable i would be restrained to the for block. But, in JavaScript, this is not the case the variable i stays in scope even after the for loop has concluded, retaining its last value after the existing loop. (This behavior is known, incidentally, as variable hoisting).

在大多数其他语言中,上面的代码将给出错误,因为变量i的“寿命”(即作用域)将被限制在for块中。 但是,在JavaScript中,即使在for循环结束后,变量i仍不在范围内,而是在现有循环之后保留其最后一个值,情况并非如此。 (顺便说一下,这种行为被称为可变提升)。

It’s also worth noting that support for block-level scopes is getting its way into JavaScript through the new let keyword. The …. Keyword is already available in JavaScript 1.7 and is slated to become an officially supported JavaScript keyword as of ECMAScript 6.

还值得注意的是,通过新的let关键字将对块级范围的支持引入JavaScript。 …。 关键字已在JavaScript 1.7中提供,并且自ECMAScript 6起已成为正式支持JavaScript关键字。

3)创建内存泄漏 (3) Creating memory leaks)

Memory leaks can become the inevitable JavaScript problems if you aren’t consciously coding to avoid them. There are multiple ways for them to take place. Here, we’ll demonstrate a couple of their more common occurrences.

如果您没有有意识地进行编码以避免避免,则内存泄漏可能成为不可避免JavaScript问题。 它们有多种发生方式。 在这里,我们将展示它们的一些较常见的情况。

Memory Leak Example 1: Dangling references to defunct objects

内存泄漏示例1:悬挂对已失效对象的引用

Consider the following code:

考虑以下代码:

var theThing = null;
var replaceThing = function () {
var priorThing = theThing; // hold on to the prior thing
var unused = function () {
// ‘unused’ is the only place where ‘priorThing’ is referenced,
// but ‘unused’ never gets invoked
if (priorThing) {
console.log(“hi”);
}
};
theThing = {
longStr: new Array(1000000).join(‘*’), // create a 1MB object
someMethod: function () {
console.log(someMessage);
}
};
};
setInterval(replaceThing, 1000); // invoke `replaceThing’ once every second

If you run the above code and track memory usage, you’ll find that you’ve got a huge memory leak, leaking a complete megabyte per second! And even a manual GC doesn’t help. So it seems like we’re leaking longStr every time replaceThing is called. But why?

如果运行上面的代码并跟踪内存使用情况,则会发现内存泄漏巨大,每秒泄漏完整的兆字节! 甚至手动GC也无济于事。 因此,它似乎就像我们漏水longStr每次replaceThing被调用。 但为什么?

Let’s find things in more detail:

让我们更详细地查找事物:

Each theThing object contains its own 1MB longStr object. Every second, when we call replaceThing, it holds on to a reference to the prior theThing object in priorThing. But we still wouldn’t think this would be an issue, since each time through, the formerly referenced priorThing would be dereferenced (when priorThing is reset via priorThing = theThing;). And additionally, is only referenced in the main body of replaceThing and in the function unused which is, in fact, never used.

每个theThing对象都包含其自己的1MB longStr对象。 每隔一秒钟,当我们调用replaceThing ,它会保留对theThing中的先前theThing对象的priorThing 。 但是,我们仍然不会认为这将是一个问题,因为通过每一次,以前引用priorThing将间接引用(当priorThing是通过复位priorThing = theThing; 另外,仅在replaceThing主体和unused的功能中引用,实际上从未使用过。

So once more we’re left speculating why there is a memory leak here!?

因此,我们再一次推测为什么这里存在内存泄漏!

To know what’s going on, we need to understand how things are working in JavaScript under the hood. The general way closures are implemented is that every function object has a link to a dictionary-style object representing its lexical scope. If both functions defined inside replaceThing actuality used priorThing, it would be essential that they both get the same object, even if priorThing gets assigned to over and over, so both functions share a similar lexical environment. But as quickly as any closure uses a variable, it finished up in the lexical environment shared all closures in that scope. And, that little nuance is what leads to this gnarly memory leak. (More details on this accessible here.)

要了解发生了什么,我们需要了解引擎盖下的事物是如何工作的。 闭包的一般实现方式是,每个函数对象都有一个指向表示其词法范围的字典式对象的链接。 如果在replaceThing现实中定义的两个函数都使用了priorThing ,那么即使priorThingpriorThing分配给它们,获取它们的同一对象也是priorThing ,因此这两个函数共享相似的词法环境。 但是,只要任何闭包都使用了变量,它就会在词汇环境中完成共享该范围内所有闭包的操作。 而且,这种细微差别是导致这种陈旧的内存泄漏的原因。 (有关更多详细信息,请点击此处。)

Memory Leak Example 2: Circular references

内存泄漏示例2:循环引用

Let’s take a look at this code fragment:

让我们看一下这段代码片段:

function addClickHandler(element) {
element.click = function onClick(e) {
alert(“Clicked the “ + element.nodeName)
}
}

Here, onClick has a closure which retains a reference to element (via element.nodeName). By also assigning onClick to element.click, the circular reference is created; for example: element -> onClick -> element -> onClick -> element…Interestingly, even if the element is removed from the DOM, the circular self-reference above would prevent element and onClick from being collected, and so, a memory leak.

在这里, onClick有一个闭包,该闭包保留对element的引用(通过element.nodeName )。 通过还将onClick分配给element.click ,可以创建循环引用。 例如: element - > onClick - > element - > onClick - > element ...有趣的是,即使该element从DOM移除,上述将防止圆形自参考elementonClick收集从等,内存泄漏。

Avoiding Memory Leaks: What you need to understand?

避免内存泄漏:您需要了解什么?

JavaScript’s memory management (and, in special, garbage collection) is largely based on the idea of object reachability.

JavaScript的内存管理(特别是垃圾回收)主要基于对象可访问性的思想。

The following objects are supposed to be reachable and are known as “roots”:

以下对象应该是可到达的,被称为“根”:

  • Objects referenced from anywhere in the current call stack (that’s, all local variables and parameters in the functions presently being invoked, and all the variables in the closure’s scope)

    从当前调用堆栈中任何地方引用的对象(即,当前正在调用的函数中的所有局部变量和参数,以及闭包作用域中的所有变量)
  • All global variables.

    所有全局变量。

Objects are kept in memory at least as long as they’re accessible from any of the roots via a reference, or a chain of references.

至少在对象可以通过引用或引用链从任何根访问对象的情况下,它们才会保留在内存中。

There’s a Garbage Collector (GC) in the browser which cleans memory engaged by unreachable objects: i.e., objects will be removed from memory if and only if the GC considers that they’re unreachable. Unluckily, it’s quite easy to end up with defunct “zombie” objects that are in actual no more in use but that the GC still thinks are “reachable.”

浏览器中有一个垃圾收集器(GC),用于清理无法访问的对象占用的内存:即,只有在GC认为对象无法访问时,对象才会从内存中删除。 不幸的是,很容易以实际上已经不再使用但GC仍然认为“可达”的已失效“僵尸”对象结束。

4)关于平等的困惑 (4) Confusion regarding equality)

One of the conveniences in JavaScript is that it will mechanically coerce any value being referenced in a Boolean context to a Boolean value. However, there are cases where this can be as confusing as it’s convenient.Some of the following, for example, have been known to bite many a JavaScript developer:

JavaScript的便利之一是,它将布尔值中机械引用的任何值机械地强制为布尔值。 但是,在某些情况下,这可能会很方便,令人困惑。例如,已知以下示例会咬住许多JavaScript开发人员:

// All of these evaluate to ‘true’!
console.log(false == ‘0’);
console.log(null == undefined);
console.log(“ \t\r\n” == 0);
console.log(‘’ == 0);// And these do too!
if ({}) // …
if ([]) // …

With a look to the last two, regardless of being empty (which probably leads one to believe that they would evaluate to false), both {} and [] are, in fact, objects, and any object will be coerced to a Boolean value of true in JavaScript, consistent with the ECMA-262 specification.

看看最后两个,不管是空的(可能使人相信它们会得出false ), {}[]实际上都是对象,任何对象都将被强制为布尔值在JavaScript中为true ,与ECMA-262规范一致。

As these examples imply, the rules of type coercion can often be clear as mud. Hence, unless type coercion is explicitly desired, it’s normally best to use === and !== (rather than == and !=), so as to prevent any unintended side-effects of type coercion. ( ==and != automatically execute type conversion when comparing two things, whereas === and !== Do the same appraisal without type conversation.)

正如这些示例所暗示的那样,类型强制的规则通常可以像泥泞一样清晰。 因此,除非明确需要类型强制,否则通常最好使用===!== (而不是==!= ),以防止类型强制的任何意外副作用。 (当比较两件事时, ==!=自动执行类型转换,而===!==则进行相同的评估而不进行类型对话。)

And fully as a sidepoint — but since we’re discussing type coercion and comparisons — it’s worth recalling that comparing NaN with anything (even NaN!) Will always return false. You, therefore, can’t use the equality operators (==, ===, !=, !==) to conclude whether a value is NaN or not. Instead. Use the built-in global isNaN() function:

完全是一种观点-但由于我们正在讨论类型强制和比较-值得回顾的是,将NaN与任何内容(甚至是NaN !)进行比较将始终返回false 。 因此,您不能使用等号运算符( ==, ===, !=, !== )来得出值是否为NaN结论。 代替。 使用内置的全局isNaN()函数:

console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(isNaN(NaN)); // true

5)低效的DOM操作 (5) Inefficient DOM manipulation)

JavaScript makes it fairly comfortable to manipulate the DOM (i.e., add, modify, and remove elements), but does nothing to encourage doing so efficiently.

JavaScript使操作DOM(即添加,修改和删除元素)变得相当舒适,但是并没有鼓励有效地这样做。

A general example is a code that adds a series of DOM Elements one at a time. Adding a DOM element is a lavish procedure. Code that adds numerous DOM elements consecutively is inefficient and likely not to work accordingly.

一个通用的示例是一次添加一系列DOM元素的代码。 添加DOM元素是一个繁琐的过程。 连续添加大量DOM元素的代码效率低下,并且可能无法正常工作。

One effective way when different DOM elements need to be added is to use document fragments instead, thereby enhancing both performance and efficiency.

当需要添加不同的DOM元素时,一种有效的方法是改为使用文档片段,从而提高性能和效率。

For example:

例如:

var div = document.getElementsByTagName(“my_div”);var fragment = document.createDocumentFragment();for (var e = 0; e < elems.length; e++) { // elems previously set to list of elements
fragment.appendChild(elems[e]);
}
div.appendChild(fragment.cloneNode(true));

Apart from inherently improved efficiency of this approach, creating attached DOM elements is costly, whereas creating and modifying them while detached and then attaching them delivers much better results.

除了从本质上提高此方法的效率之外,创建附加的DOM元素的成本很高,而在分离时创建和修改它们,然后附加它们可以提供更好的结果。

6)在for循环中错误使用函数定义 (6) Incorrect use of function definitions inside for loops)

Take a look at this code:

看一下这段代码:

var elements = document.getElementsByTagName(‘input’);
var n = elements.length; // assume we have 10 elements for this example
for (var i = 0; i < n; i++) {
elements[i].onclick = function() {
console.log(“This is element #” + i);
};
}

Based on this code, if there were ten input elements, clicking any of them would show “This is element #10”! This is because, by the time onclick is invoked for any of the elements, the above for loop will have concluded, and the value of i will already be ten (for all of them).

根据此代码,如果有十个输入元素,则单击其中任何一个都会显示“ This is element#10”! 这是因为,当对任何元素调用onclick ,上述for循环将结束,并且i的值已经为10(对于所有元素)。

Below is how we can rectify the above code problems, though, to achieve the desired behavior:

下面是我们如何纠正上述代码问题,以实现所需的行为:

var elements = document.getElementsByTagName(‘input’);
var n = elements.length; // assume we have 10 elements for this example
var makeHandler = function(num) { // outer function
return function() { // inner function
console.log(“This is element #” + num);
};
};
for (var i = 0; i < n; i++) {
elements[i].onclick = makeHandler(i+1);
}

In this revised version of the code, makeHandler is instantly executed each time we pass through the loops, each time receiving the then-current value of i+1 and binding it to a scoped num variable. The outer functions yield the inner functions (which also uses this scoped num variable) and the element’s onclick is set to that inner function. This guarantees that each onclick gets and uses the proper i value (via the scoped num variable).

在此代码的修订版中,每次通过循环时,都会立即执行makeHandler ,每次接收i+1的当前值并将其绑定到作用域num变量时。 外部函数产生内部函数(也使用此作用域num变量),并且元素的onclick设置为该内部函数。 这样可以确保每个onclick都可以获取和使用适当的i值(通过作用域num变量)。

7)未能适当利用原型继承 (7) Failure to appropriately leverage prototypal inheritance)

An expected high percentage of JavaScript developers fall short of fully understand, and therefore to fully leverage the features of prototypal inheritance.

预期会有大量JavaScript开发人员无法完全理解,因此无法充分利用原型继承的功能。

Following is a simple example. Consider this code:

以下是一个简单的示例。 考虑以下代码:

BaseObject = function(name) {
if(typeof name !== “undefined”) {
this.name = name;
} else {
this.name = ‘default’
}
};

Seems pretty straightforward. If you provide a name, use it, otherwise set the name to ‘default’; e.g.:

似乎很简单。 如果提供名称,请​​使用它,否则将名称设置为“默认”。 例如:

var firstObj = new BaseObject();
var secondObj = new BaseObject(‘unique’);console.log(firstObj.name); // -> Results in ‘default’
console.log(secondObj.name); // -> Results in ‘unique’

But what if we were to do this:

但是,如果我们要这样做:

delete secondObj.name;

delete secondObj.name;

We would then get:

然后,我们将得到:

console.log(secondObj.name); // -> Results in ‘undefined’

console.log(secondObj.name); // -> Results in 'undefined'

But wouldn’t it be better for this to revert to ‘default’? This can comfortably be executed, if we modify the original code to leverage prototypal inheritance, as below:

但是将其恢复为“默认”会不会更好? 如果我们修改原始代码以利用原型继承,则可以轻松地执行此操作,如下所示:

BaseObject = function (name) {
if(typeof name !== “undefined”) {
this.name = name;
}
};BaseObject.prototype.name = ‘default’;

With this version, BaseObject inherits the name property from its prototype object, where it is set (by default) to ‘default’. Hence, if the constructor is called without a name, the name will default to default. And likewise, if the name property is detached from an instance of BaseObject, the prototype chain will then be searched and the name property will be regained from the prototype object where its value is still ‘default’. So now we get:

在此版本中, BaseObject继承自其prototype对象的name属性,该对象在默认情况下被设置为'default' 。 因此,如果在没有名称的情况default调用构造函数,则该名称将默认为default 。 同样,如果将name属性与BaseObject的实例BaseObject ,则将搜索原型链,并从其值仍为'default'prototype对象中获取name属性。 现在我们得到:

var thirdObj = new BaseObject(‘unique’);
console.log(thirdObj.name); // -> Results in ‘unique’delete thirdObj.name;
console.log(thirdObj.name); // -> Results in ‘default’

8)创建对实例方法的不正确引用 (8) Creating incorrect references to instance methods)

Let’s define a simple object, and create an instance of it, as follows:

让我们定义一个简单的对象,并创建一个实例,如下所示:

var MyObject = function() {}MyObject.prototype.whoAmI = function() {
console.log(this === window ? “window” : “MyObj”);
};var obj = new MyObject();

Now, for ease, let’s specify a reference to the whoAmI method, presumably so we can access it simply be whoAmI() rather than the lengthier obj.whoAmI():

现在,为简便whoAmI ,让我们指定对whoAmI方法的引用,大概是这样,我们可以简单地通过whoAmI()而不是更长的obj.whoAmI():来访问它obj.whoAmI():

var whoAmI = obj.whoAmI;

var whoAmI = obj.whoAmI;

And just to be certain that everything looks copacetic, let’s print out the value of our new whoAmI variable:

为了确保一切看起来都是正常的,让我们打印出新的whoAmI变量的值:

console.log(whoAmI);

console.log(whoAmI);

Outputs:

输出:

function () {
console.log(this === window ? “window” : “MyObj”);
}

OK, good. Looks fine.But now, look at the dissimilarity when we invoke obj.whoAmI() vs. our convenience reference whoAmI():

好好看起来不错,但是现在来看一下调用obj.whoAmI()与便利参考whoAmI()

obj.whoAmI(); // outputs “MyObj” (as expected)
whoAmI(); // outputs “window” (uh-oh!)

What happened wrong?

出什么事了吗?

The headfake here is that, when we did the assignment var whoAmI = obj.whoAmI;, the new variable whoAmI was being defined in the global namespace. As an effect, its value of this is window, not the obj instance of MyObject!

最令人头疼的是,当我们执行赋值操作时, var whoAmI = obj.whoAmI; ,即在全局名称空间中定义的新变量whoAmI 。 作为一个效果,它的价值thiswindow ,不是obj的实例MyObject

Thus, if we really need to create a reference to an existing method of an object, we need to be sure to do it within that object’s namespace, to preserve the value of this. One way of doing this would be, for example, as follows:

因此,如果确实需要创建对对象现有方法的引用,则需要确保在该对象的名称空间中进行引用,以保留this的值。 例如,一种这样做的方式如下:

var MyObject = function() {}MyObject.prototype.whoAmI = function() {
console.log(this === window ? “window” : “MyObj”);
};var obj = new MyObject();
obj.w = obj.whoAmI; // still in the obj namespaceobj.whoAmI(); // outputs “MyObj” (as expected)
obj.w(); // outputs “MyObj” (as expected)

9)提供一个字符串作为setTimeout或setInterval的初始参数 (9) Providing a string as the initial argument to setTimeout or setInterval)

For beginners, let’s be aware of something here: Providing a string as the first argument to setTimeout or setInterval isn’t itself a mistake per se. It’s a perfectly genuine JavaScript code. The problem here is more one of performance and efficiency. What is not often explained is that, under the hood, if you pass in a string as the primary argument to setTimeout or setInterval, it will be passed to the function constructor to be transformed into a new function. This procedure can be slow and inefficient and is rarely necessary.

对于初学者,让我们在这里了解一些事情:将字符串作为setTimeoutsetInterval的第一个参数本身本身并不是错误。 这是一个非常真实JavaScript代码。 这里的问题不仅仅是性能和效率之一。 通常不解释的是,如果在setTimeout将字符串作为主要参数传递给setTimeoutsetInterval ,它将被传递给函数构造函数以转换为新函数。 此过程可能很慢且效率低下,几乎不需要。

The alternative to passing a string as the first argument to these methods is to instead pass in a function. Let’s take a look at the following example.

将字符串作为这些方法的第一个参数传递的替代方法是传递一个函数。 让我们看下面的例子。

Here, then, would be fairly common use of setInterval and setTimeout, passing a string as the first parameter:

那么,这里将使用setIntervalsetTimeout相当普遍,将字符串作为第一个参数:

setInterval(“logTime()”, 1000);
setTimeout(“logMessage(‘“ + msgValue + “‘)”, 1000);

The better option would be to pass in a function as the initial argument; e.g.:

更好的选择是传入一个函数作为初始参数。 例如:

setInterval(logTime, 1000); // passing the logTime function to setIntervalsetTimeout(function() { // passing an anonymous function to setTimeout
logMessage(msgValue); // (msgValue is still accessible in this scope)
}, 1000);

10)无法使用“严格模式” (10) Failure to use “strict mode”)

“Strict mode” is an approach to voluntarily enforce stricter parsing and error controlling on your JavaScript code at runtime, as well as making it more secure.While, undoubtedly, failing to use strict mode isn’t a “mistake” per se, its use is largely being suggested, and its omission is increasingly considered a bad form.

“严格模式”是一种在运行时自愿对JavaScript代码强制执行更严格的解析和错误控制以及使其更安全的方法。毫无疑问,不使用严格模式本身并不是“错误”,但是很大程度上建议使用,并且其遗漏被认为是不好的形式。

Below have been described some major benefits of strict mode:

下面描述了严格模式的一些主要优点:

  1. Makes debugging easier:

    使调试更加容易:

    Code errors that would otherwise have been overlooked or would have failed calmly will now provide errors or throw exceptions, alerting you sooner to issues in your code and referring you more quickly to their source.

    现在,本来可以被忽略或平静地失败的代码错误将提供错误或引发异常,从而更快地提醒您代码中的问题,并更快地将其引向其来源。

  2. Avoids accidental globals:

    避免意外的全局变量:

    In the absence of strict mode, assigning a value to an undeclared variable, habitually creates a global variable with that name. This is one of the most typical errors in JavaScript. In strict mode, attempting to do so throws an error.

    在没有严格模式的情况下,将值分配给未声明的变量通常会创建一个具有该名称的全局变量。 这是JavaScript中最典型的错误之一。 在严格模式下,尝试这样做会引发错误。

  3. Eliminates this coercion:

    消除this胁迫

    Without strict mode, a reference to a

    如果没有严格模式,则对

    this value of null or undefined is automatically coerced to the global. This can lead to multiple headfakes and pull-out-your-hair kind of bugs. In strict mode, referencing a this value of null or undefined throws an error.

    this null或undefined值将自动强制为全局值。 这可能会导致多次假冒和拔出头发的错误。 在严格模式下,引用this值为null或undefined会引发错误。

  4. Disallows duplicate property names or parameter values:

    不允许重复的属性名称或参数值:

    Strict mode throws an error when it notices a duplicate named property in an object (e.g.,

    严格模式在发现对象中有重复的命名属性时(例如,

    var object = {foo: “bar”, foo: “baz”};) or a duplicate named argument for a function (e.g., function foo(val1, val2, val1){}), thereby catching what is nearly certainly a bug in your code that you might otherwise have wasted many of time tracking down.

    var object = {foo: “bar”, foo: “baz”}; )或函数的重复命名实function foo(val1, val2, val1){} (例如, function foo(val1, val2, val1){} ),从而捕获了代码中几乎可以确定的错误,否则您可能会浪费很多时间进行跟踪。

  5. Makes eval() safer:There are some differences in the manner eval() behaves in strict mode and in non-strict mode. Most importantly, in strict mode, variables and functions declared inside of an eval() statement aren’t created in the containing scope (they’re created in the containing scope in non-strict mode, which can also be a general source of problems).

    使eval()更安全: eval()在严格模式和非严格模式下的行为方式有所不同。 最重要的是,在严格模式下,不会在包含范围内创建在eval()语句内声明的变量和函数(它们是在非严格模式下在包含范围内创建的,这也可能是问题的一般根源) )。

  6. Throws error on invalid usage of delete :

    无效使用delete引发错误

    The

    delete operator (known to remove properties from objects) cannot be used on the non-configurable properties of the object. Non-strict code will fail silently when an effort to delete a non-configurable property is made. Strict mode will throw an error in such a case.

    delete操作符(已知可以从对象中删除属性)不能用于对象的不可配置属性。 当尝试删除不可配置的属性时,非严格代码将静默失败。 在这种情况下,严格模式将引发错误。

判决 (Verdict)

As is true with any technology, the better you know why and how JavaScript works and doesn’t work, the more concise your code will be, and the more you’ll be able to harness to the true power of the language effectually. Conversely, lack of understanding of JavaScript paradigms and concepts is indeed where various JavaScript problems lie.

就像任何技术一样,您越了解JavaScript为何起作用以及如何起作用以及不起作用,您的代码将越简洁,并且您越能有效地利用语言的真正力量。 相反,缺乏对JavaScript范式和概念的理解确实是各种JavaScript问题所在。

Comprehensively familiarizing yourself with the language’s nuances and subtitles is the most effective strategy for strengthening your proficiency and increasing your productivity. Avoid various common JavaScript mistakes that will aid when your JavaScript isn’t working.

全面熟悉该语言的细微差别和字幕是增强您的熟练程度和提高生产率的最有效策略。 避免各种常见JavaScript错误,这些错误会在JavaScript无法正常工作时提供帮助。

翻译自: https://code.likeagirl.io/ten-practices-to-avoid-being-a-java-developer-74bbc97380d1

java开发人员

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值