Table of Contents
Elevation
First Class Citizen
Object
Function summary
Closing summary
FAQs about JavaScript Features (FAQ)
What is the difference between "==" and "===" in JavaScript?
Why does JavaScript have both null and undefined?
What is the improvement in JavaScript?
What is the difference between global variables and local variables in JavaScript?
What is the "this" keyword in JavaScript?
What are closures in JavaScript?
What is the difference between function declarations and function expressions in JavaScript?
What is the difference between "let", "var" and "const" in JavaScript?
What is the difference between objects and arrays in JavaScript?
What is the difference between methods and functions in JavaScript?
Home Web Front-end JS Tutorial Three JavaScript Quirks That Java/C Developers Should Know

Three JavaScript Quirks That Java/C Developers Should Know

Feb 20, 2025 am 10:28 AM

Three JavaScript Quirks That Java/C Developers Should Know

Core points

  • Unlike C or Java, JavaScript's scope is function-based, not block-based; variables declared in if or for blocks are promoted to the top of the function or global scope.
  • Elevation in JavaScript means that variables and function declarations are moved to the top of their included scope during compilation, but initialization is not elevated.
  • Functions in JavaScript are treated as first-class citizens, meaning they can be stored in variables, passed as parameters, returned by other functions, and have properties like objects.
  • The with statement (dynamic scope variable) in JavaScript has been deprecated because it can cause runtime errors and is confusing in nature.
  • JavaScript supports closures, allowing functions to access external functions' variables after returning, thereby enhancing data privacy and enabling powerful programming modes such as modules and private variables.
table.sp_table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
}
table.sp_table td, table.sp_table th {
  border: solid 1px #ccc;
  padding: 10px;
  line-height: 1.5;
  text-align: center;
  width: 20%;
}
table.sp_table tr td:first-child {
  font-weight: bold;
}
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

JavaScript can be a deceptive language, it can be painful because it is not 100% consistent. It is known that it does have some bad parts of i.e. confusing or redundant functions that should be avoided: the infamous statements, implicit global variables, and comparison behavior exceptions are probably most famous of. JavaScript is one of the most successful flame generators in history! Apart from the flaws it has (partially solved in the new ECMAScript specification), most programmers hate JavaScript for two reasons: - DOM, they mistakenly think it is equivalent to the JavaScript language, which has a very bad API . - They moved from languages ​​like C and Java to JavaScript. The syntax of JavaScript fooled them into believing that it worked the same way as those imperative languages. This misunderstanding can lead to confusion, frustration, and error. withThis is why, usually, JavaScript has a worse reputation than it deserves. In my career, I have noticed some patterns: Most developers with Java or C/C backgrounds think the same language features in JavaScript, and they are completely different. This article collects the most troublesome language features, comparing Java approaches to JavaScript approaches to show differences and highlighting best practices in JavaScript.

Scope

Most developers start using JavaScript because they are forced to do so, and almost all developers start writing code before they spend time learning the language. Each such developer has been fooled by JavaScript scope at least once. Because JavaScript's syntax is very similar to that of C-series (intentionally), separating the body of functions, if and for with braces, people would reasonably expect the lexical block-level scope. Unfortunately, this is not the case. First, in JavaScript, variable scope is determined by functions, not by brackets. In other words, if and for bodies do not create new scopes, and variables declared in their bodies are actually promoted, i.e. created at the beginning of the innermost function that declares it, otherwise global scope. Second, the existence of with statements forces JavaScript scope to become dynamic and cannot be determined until runtime. You may not be surprised to hear that the use of with statements has been deprecated: JavaScript without with will actually be a lexical scoped language, i.e., the scope can be completely determined by looking at the code. Formal, in JavaScript, there are four ways to get into scope: - Language Definition: By default, all scopes contain names this and arguments. - Formal Parameters: The scope of any (formal) parameter declared for a function belongs to the body of the function. - Function declaration. - Variable declaration.

Another complexity is caused by the implicit global scope of variable assignments for (implicitly) not declared in the var keyword. This madness is combined with implicit assignment of global scope to this references when calling a function without explicit binding (more on the next section). Before digging into the details, let's clarify what good patterns can be used to avoid confusion: use strict pattern ('use strict';), and move all variables and function declarations to the top of each function; Avoid declaring variables within for and if blocks, and declaration of functions within those blocks (this is beyond the scope of this article for different reasons).

Elevation

Elevation is a simplified method for explaining actual behavior of statements. The promoted variable is declared at the beginning of the function it contains and is initialized to undefined. The assignment then takes place in the actual line of the original declaration. Please see the following example:

table.sp_table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
}
table.sp_table td, table.sp_table th {
  border: solid 1px #ccc;
  padding: 10px;
  line-height: 1.5;
  text-align: center;
  width: 20%;
}
table.sp_table tr td:first-child {
  font-weight: bold;
}
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

What is the value you expect to print to the console? Would you be surprised by the following output?

table.sp_table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
}
table.sp_table td, table.sp_table th {
  border: solid 1px #ccc;
  padding: 10px;
  line-height: 1.5;
  text-align: center;
  width: 20%;
}
table.sp_table tr td:first-child {
  font-weight: bold;
}
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

In the if block, the var statement does not declare a local copy of the variable i, but rather overwrites the previously declared variable. Note that the first console.log statement prints the actual value of the variable i, which is initialized to undefined. You can test it by using the "use strict"; directive as the first line in the function. In strict mode, variables must be declared before using them, but you can check that the JavaScript engine does not report errors because of the declaration. By the way, please note that you won't report an error because of redeclaring var: If you want to catch such errors, you'd better use a linter like JSHint or JSLint to handle your code. Now let's look at another example to highlight another error-prone usage of variable declarations:

function myFunction() {
  console.log(i);
  var i = 0;
  console.log(i);
  if (true) {
    var i = 5;
    console.log(i);
  }
  console.log(i);
}
Copy after login
Copy after login
Copy after login

Although you may expect differently, the if body is executed because a local copy of the variable named test() is declared inside the notNull function, and it is promoted by . Type mandatory works here too.

Function declaration and function expression

Elevation is not only applicable to variables, but

function expressions (they are actually variables) and function declarations will also be promoted. This topic needs to be handled more carefully than I did here, but in short, function declarations behave roughly the same as function expressions, except that their declarations are moved to the beginning of their scope. Consider the following example showing the behavior of function declaration:

<code>undefined
0
5
5</code>
Copy after login
Copy after login
Copy after login
Now compare this with the following example showing the behavior of function expressions:

var notNull = 1;
function test() {
  if (!notNull) {
    console.log("Null-ish, so far", notNull);
    for(var notNull = 10; notNull < 20; notNull++) {
      //..
    }
    console.log("Now it's not null", notNull);
  }
  console.log(notNull);
}
Copy after login
Copy after login
Copy after login
Please refer to the reference section for further understanding of these concepts.

with

The following example shows a situation where the scope can only be determined at runtime:

function foo() {
    // 函数声明
    function bar() {
        return 3;
    }
    return bar();

    // 此函数声明将被提升并覆盖之前的声明
    function bar() {
        return 8;
    }
}
Copy after login
Copy after login
If

has a field named y, the function x will return foo(), otherwise 123 will be returned. This coding practice may be the source of runtime errors, so it is highly recommended that you avoid the y.x statement. with

Looking forward: ECMAScript 6

The

ECMAScript 6 specification will add a fifth method to add block-level scope: the

statement. Consider the following code: let

function foo() {
    // 函数表达式
    var bar = function() {
        return 3;
    };
    return bar();

    // 变量 bar 已经存在,并且永远不会到达此代码
    var bar = function() {
        return 8;
    };
}
Copy after login
In ECMAScript 6, using

inside the body of if declares let to create a new variable local to the i block. As a non-standard alternative, the if block can be declared as follows: let

function foo(y) {
  var x = 123;
  with(y) {
    return x;
  }
}
Copy after login
In the above code, the variables

and i only exist within the block. At the time of writing, support for j is limited, even for Chrome. let

Scope summary

The following table summarizes the scope in different languages:

特性 Java Python JavaScript 警告
作用域 词法(块) 词法(函数、类或模块) 它与 Java 或 C 的工作方式大相径庭
块作用域 let 关键字(ES6) 再一次警告:这不是 Java!
提升 不可能! 仅提升变量和函数表达式的声明。对于函数声明,也会提升定义
函数 作为内置类型 回调/命令模式对象(或 Java 8 的 lambda)
动态创建 evalFunction 对象 eval 存在安全问题,Function 对象可能无法按预期工作
属性 可以具有属性 无法限制对函数属性的访问
闭包 弱化,只读,在匿名内部类中 弱化,只读,在嵌套的 def 中 内存泄漏

Function

Another very misunderstood feature of JavaScript is that functions, especially in imperative programming languages ​​such as Java, there is no concept of functions. In fact, JavaScript is a functional programming language. Well, it's not a pure functional programming language like Haskell -- it still has an imperative style after all, and encourages mutability rather than just allowing, just like Scala. However, JavaScript can be used as a purely functional programming language, with function calls without any side effects.

First Class Citizen

Functions in JavaScript can be treated like any other type, such as String and Number: they can be stored in variables, passed as parameters to functions, returned by functions, and stored in an array. Functions can also have properties and can be changed dynamically, because...

Object

A very surprising fact for most JavaScript newbies is that functions are actually objects. In JavaScript, each function is actually a Function object. Function constructor creates a new Function object:

table.sp_table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
}
table.sp_table td, table.sp_table th {
  border: solid 1px #ccc;
  padding: 10px;
  line-height: 1.5;
  text-align: center;
  width: 20%;
}
table.sp_table tr td:first-child {
  font-weight: bold;
}
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

This is almost equivalent to:

function myFunction() {
  console.log(i);
  var i = 0;
  console.log(i);
  if (true) {
    var i = 5;
    console.log(i);
  }
  console.log(i);
}
Copy after login
Copy after login
Copy after login

I say they are almost equivalent because using the Function constructor is less efficient, produces anonymous functions and does not create closures for their creation context. Function objects are always created in the global scope. Function (the type of function) is built on Object. This can be easily seen by checking any function you declare:

<code>undefined
0
5
5</code>
Copy after login
Copy after login
Copy after login

This means that the function can and does have properties. Some of these are assigned to functions at creation time, such as names or lengths. These properties return the name and number of parameters in the function definition, respectively. Consider the following example:

var notNull = 1;
function test() {
  if (!notNull) {
    console.log("Null-ish, so far", notNull);
    for(var notNull = 10; notNull < 20; notNull++) {
      //..
    }
    console.log("Now it's not null", notNull);
  }
  console.log(notNull);
}
Copy after login
Copy after login
Copy after login

But you can even set new properties for any function yourself:

function foo() {
    // 函数声明
    function bar() {
        return 3;
    }
    return bar();

    // 此函数声明将被提升并覆盖之前的声明
    function bar() {
        return 8;
    }
}
Copy after login
Copy after login

Function summary

The following table describes functions in Java, Python, and JavaScript:

特性 Java Python JavaScript 警告
函数作为内置类型 lambda,Java 8 回调/命令模式对象(或 Java 8 的 lambda)
动态创建 evalFunction 对象 eval 存在安全问题,Function 对象可能无法按预期工作
属性 可以具有属性 无法限制对函数属性的访问

Closing

If I were asked to choose my favorite JavaScript feature, I would choose the closure without hesitation. JavaScript is the first mainstream programming language to introduce closures. As you know, Java and Python have long had weakened versions of closures from which you can only read (some) values ​​of enclosed scopes. For example, in Java, anonymous inner classes provide closure-like functionality with certain limitations. For example, the final local variables can only be used in their scope—more precisely, their values ​​can be read. JavaScript allows full access to external scoped variables and functions. They can be read, written, and even hidden by local definitions if needed: you can see examples of all these cases in the Scope section. What's more interesting is that the function created in the closure remembers the environment in which it was created. By combining closures and function nesting, you can have external functions return internal functions without executing them. Additionally, you can make local variables of external functions last long in the closure of their internal functions, even if the execution of the function that declares them has ended. This is a very powerful feature, but it also has its drawbacks, as it is a common cause of memory leaks in JavaScript applications. Some examples will illustrate these concepts:

table.sp_table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
}
table.sp_table td, table.sp_table th {
  border: solid 1px #ccc;
  padding: 10px;
  line-height: 1.5;
  text-align: center;
  width: 20%;
}
table.sp_table tr td:first-child {
  font-weight: bold;
}
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

The above makeCounter() function creates and returns another function that tracks the environment it created. Although the execution of counter is finished when the variable makeCounter() is allocated, the local variable i remains in the closure of displayCounter and can therefore be accessed inside its body. If we want to run makeCounter again, it will create a new closure where the entry for i is different:

function myFunction() {
  console.log(i);
  var i = 0;
  console.log(i);
  if (true) {
    var i = 5;
    console.log(i);
  }
  console.log(i);
}
Copy after login
Copy after login
Copy after login

To make it more interesting, we can update the makeCounter() function to accept a parameter:

<code>undefined
0
5
5</code>
Copy after login
Copy after login
Copy after login

External function parameters are also saved in the closure, so we don't need to declare local variables this time. Each call makeCounter() will remember the initial value we set and continue counting. Closures are essential for many basic JavaScript patterns: namespaces, modules, private variables, memory are just the most famous. For example, let's see how to simulate private variables for an object:

var notNull = 1;
function test() {
  if (!notNull) {
    console.log("Null-ish, so far", notNull);
    for(var notNull = 10; notNull < 20; notNull++) {
      //..
    }
    console.log("Now it's not null", notNull);
  }
  console.log(notNull);
}
Copy after login
Copy after login
Copy after login

Using this pattern, using closures, we can create a wrapper for the property name and use our own setters and getters. ES5 makes this much easier because you can create objects for their properties using getters and setters and control access to the properties themselves at the finest grain.

Closing summary

The following table describes closures in Java, Python, and JavaScript:

特性 Java Python JavaScript 警告
闭包 弱化,只读,在匿名内部类中 弱化,只读,在嵌套的 def 中 内存泄漏
记忆化模式 必须使用共享对象 可以使用列表或字典 最好使用惰性求值
命名空间/模块模式 不需要 不需要
私有属性模式 不需要 不可能 可能令人困惑

Conclusion

In this article, I introduce three features of JavaScript that are often misunderstood by developers from different languages, especially Java and C. In particular, we discuss concepts such as scope, promotion, functions and closures. If you want to dig into these topics, here is a list of some articles you can read: - Scope in JavaScript - Function Declarations and Function Expressions - let Statements and let Blocks

FAQs about JavaScript Features (FAQ)

What is the difference between "==" and "===" in JavaScript?

In JavaScript, "==" and "===" are comparison operators, but they work differently. The “==” operator is called the loose equality operator. It compares whether the two values ​​are equal after performing any necessary type conversion. This means that if you compare a number to a string with a numeric literal, it will return true. For example, "5" == 5 will return true. On the other hand, "===" is a strict equality operator. It does not perform type conversion, so if the two value types are different, it returns false. For example, "5" === 5 will return false because one is a string and the other is a number.

Why does JavaScript have both null and undefined?

In JavaScript, null and undefined are special values ​​that do not exist. However, they are used slightly differently. Undefined means that the variable has been declared but has not been assigned yet. null, on the other hand, is an assignment value, indicating no value or no object. It implies that the value of the variable does not exist, while undefined means that the variable itself does not exist.

What is the improvement in JavaScript?

Elevation is a mechanism in JavaScript that moves variables and function declarations to the top of its included scope during the compilation phase. This means you can use variables and functions before declaring them. However, it should be noted that only declarations will be promoted, and initialization will not be promoted. If the variable is declared and initialized after using it, the value will be undefined.

What is the difference between global variables and local variables in JavaScript?

In JavaScript, variables can be global or local variables. Global variables are variables declared outside any function, or variables declared with the "var" keyword at all. It can be accessed from any function in the script. Local variables, on the other hand, are variables declared within a function using the "var" keyword. It can only be accessed within the functions it declares.

What is the "this" keyword in JavaScript?

The "this" keyword in JavaScript is a special keyword, which refers to the context of calling a function. Its value depends on how the function is called. In a method, "this" refers to the owner object. Individually, "this" refers to a global object. In a function, "this" refers to a global object. In an event, "this" refers to the element that receives the event.

What are closures in JavaScript?

A closure in JavaScript is a function that can access its own scope, the scope and global scope of external functions, as well as access function parameters and variables. This allows the function to access variables in the returned external function, keeping the variables in memory, and allows data privacy and function factories.

What is the difference between function declarations and function expressions in JavaScript?

In JavaScript, functions can be defined in many ways, two of which are function declarations and function expressions. A function declaration defines a named function, and the declaration is promoted, allowing the function to be used before defining it. A function expression defines a function in an expression and is not promoted, meaning it cannot be used before its definition.

What is the difference between "let", "var" and "const" in JavaScript?

"let", "var" and "const" are all used to declare variables in JavaScript, but they have different scope rules. "var" is function scoped, meaning it can only be used within the functions it declares. "let" and "const" are block-scoped, meaning they can only be used within the blocks they declare. The difference between "let" and "const" is that "let" allows you to reassign variables, while "const" does not.

What is the difference between objects and arrays in JavaScript?

In JavaScript, objects and arrays are used to store data, but they are stored in different ways. An object is a collection of properties, where each property is a key-value pair. A key is a string and a value can be any data type. An array is a special type of object that represents a list of items. Keys are numeric indexes, and values ​​can be of any data type.

What is the difference between methods and functions in JavaScript?

In JavaScript, a function is a block of code designed to perform a specific task, and it is a separate entity that can be used as needed. On the other hand, a method is a function associated with an object, or in other words, a method is a property of an object as a function. Methods are defined in the same way as ordinary functions, except that they must be assigned values ​​as attributes of objects.

The above is the detailed content of Three JavaScript Quirks That Java/C Developers Should Know. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What should I do if I encounter garbled code printing for front-end thermal paper receipts? What should I do if I encounter garbled code printing for front-end thermal paper receipts? Apr 04, 2025 pm 02:42 PM

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

Demystifying JavaScript: What It Does and Why It Matters Demystifying JavaScript: What It Does and Why It Matters Apr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Who gets paid more Python or JavaScript? Who gets paid more Python or JavaScript? Apr 04, 2025 am 12:09 AM

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

How to merge array elements with the same ID into one object using JavaScript? How to merge array elements with the same ID into one object using JavaScript? Apr 04, 2025 pm 05:09 PM

How to merge array elements with the same ID into one object in JavaScript? When processing data, we often encounter the need to have the same ID...

Is JavaScript hard to learn? Is JavaScript hard to learn? Apr 03, 2025 am 12:20 AM

Learning JavaScript is not difficult, but it is challenging. 1) Understand basic concepts such as variables, data types, functions, etc. 2) Master asynchronous programming and implement it through event loops. 3) Use DOM operations and Promise to handle asynchronous requests. 4) Avoid common mistakes and use debugging techniques. 5) Optimize performance and follow best practices.

How to achieve parallax scrolling and element animation effects, like Shiseido's official website?
or:
How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? How to achieve parallax scrolling and element animation effects, like Shiseido's official website? or: How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? Apr 04, 2025 pm 05:36 PM

Discussion on the realization of parallax scrolling and element animation effects in this article will explore how to achieve similar to Shiseido official website (https://www.shiseido.co.jp/sb/wonderland/)...

The Evolution of JavaScript: Current Trends and Future Prospects The Evolution of JavaScript: Current Trends and Future Prospects Apr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

The difference in console.log output result: Why are the two calls different? The difference in console.log output result: Why are the two calls different? Apr 04, 2025 pm 05:12 PM

In-depth discussion of the root causes of the difference in console.log output. This article will analyze the differences in the output results of console.log function in a piece of code and explain the reasons behind it. �...

See all articles