- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
翻译: Português, Spanish, 繁體中文, 简体中文
standard 规则列表,太多不必阅读。
了解 standard
的最好方式是安装它,然后写代码尝试。
eslint: indent
function hello (name) { console.log('hi', name) }
eslint: quotes
console.log('hello there') $("")
eslint: no-unused-vars
function myFunction () { var result = something() // ✗ avoid }
eslint: keyword-spacing
if (condition) { ... } // ✓ ok if(condition) { ... } // ✗ avoid
eslint: space-before-function-paren
function name (arg) { ... } // ✓ ok function name(arg) { ... } // ✗ avoid run(function () { ... }) // ✓ ok run(function() { ... }) // ✗ avoid
===
Không sử dụng ==
.obj == null
检测 null || undefined
.eslint: eqeqeq
if (name === 'John') // ✓ ok if (name == 'John') // ✗ avoid
if (name !== 'John') // ✓ ok if (name != 'John') // ✗ avoid
eslint: space-infix-ops
// ✓ ok var x = 2 var message = 'hello, ' + name + '!'
// ✗ avoid var x=2 var message = 'hello, '+name+'!'
eslint: comma-spacing
// ✓ ok var list = [1, 2, 3, 4] function greet (name, options) { ... }
// ✗ avoid var list = [1,2,3,4] function greet (name,options) { ... }
khác
与它的大括号同行。eslint: brace-style
// ✓ ok if (condition) { // ... } else { // ... }
// ✗ avoid if (condition) { // ... } else { // ... }
nếu như
语句如果包含多个语句则使用大括号。eslint: curly
// ✓ ok if (options.quiet !== true) console.log('done')
// ✓ ok if (options.quiet !== true) { console.log('done') }
// ✗ avoid if (options.quiet !== true) console.log('done')
err
参数。eslint: handle-callback-err
// ✓ ok run(function (err) { if (err) throw err window.alert('done') })
// ✗ avoid run(function (err) { window.alert('done') })
window.
.tài liệu
, console
Và navigator
.eslint: no-undef
window.alert('hi') // ✓ ok
eslint: no-multiple-empty-lines
// ✓ ok var value = 'hello world' console.log(value)
// ✗ avoid var value = 'hello world' console.log(value)
?
Và :
放在各自的行上。eslint: operator-linebreak
// ✓ ok var location = env.development ? 'localhost' : 'www.api.com' // ✓ ok var location = env.development ? 'localhost' : 'www.api.com' // ✗ avoid var location = env.development ? 'localhost' : 'www.api.com'
khác nhau
声明,每个声明占一行。eslint: one-var
// ✓ ok var silent = true var verbose = true // ✗ avoid var silent = true, verbose = true // ✗ avoid var silent = true, verbose = true
=
),而不是一个等式 (===
) 的误写。eslint: no-cond-assign
// ✓ ok while ((m = text.match(expr))) { // ... } // ✗ avoid while (m = text.match(expr)) { // ... }
eslint: block-spacing
function foo () {return true} // ✗ avoid function foo () { return true } // ✓ ok
eslint: camelcase
function my_function () { } // ✗ avoid function myFunction () { } // ✓ ok var my_var = 'hello' // ✗ avoid var myVar = 'hello' // ✓ ok
eslint: comma-dangle
var obj = { message: 'hello', // ✗ avoid }
eslint: comma-style
var obj = { foo: 'foo' ,bar: 'bar' // ✗ avoid } var obj = { foo: 'foo', bar: 'bar' // ✓ ok }
.
应当与属性同行。eslint: dot-location
console. log('hello') // ✗ avoid console .log('hello') // ✓ ok
elint: eol-last
eslint: func-call-spacing
console.log ('hello') // ✗ avoid console.log('hello') // ✓ ok
eslint: key-spacing
var obj = { 'key' : 'value' } // ✗ avoid var obj = { 'key' :'value' } // ✗ avoid var obj = { 'key':'value' } // ✗ avoid var obj = { 'key': 'value' } // ✓ ok
eslint: new-cap
function animal () {} var dog = new animal() // ✗ avoid function Animal () {} var dog = new Animal() // ✓ ok
eslint: new-parens
function Animal () {} var dog = new Animal // ✗ avoid var dog = new Animal() // ✓ ok
eslint: accessor-pairs
var person = { set name (value) { // ✗ avoid this.name = value } } var person = { set name (value) { this.name = value }, get name () { // ✓ ok return this.name } }
siêu
.eslint: constructor-super
class Dog { constructor () { super() // ✗ avoid } } class Dog extends Mammal { constructor () { super() // ✓ ok } }
eslint: no-array-constructor
var nums = new Array(1, 2, 3) // ✗ avoid var nums = [1, 2, 3] // ✓ ok
arguments.callee
Và arguments.caller
.eslint: no-caller
function foo (n) { if (n <= 0) return arguments.callee(n - 1) // ✗ avoid } function foo (n) { if (n <= 0) return foo(n - 1) }
eslint: no-class-assign
class Dog {} Dog = 'Fido' // ✗ avoid
hằng số
声明的变量。eslint: no-const-assign
const score = 100 score = 125 // ✗ avoid
eslint: no-constant-condition
if (false) { // ✗ avoid // ... } if (x === 0) { // ✓ ok // ... } while (true) { // ✓ ok // ... }
eslint: no-control-regex
var pattern = /\x1f/ // ✗ avoid var pattern = /\x20/ // ✓ ok
cửa sổ
语句。eslint: no-window
function sum (a, b) { window // ✗ avoid return a + b }
xóa bỏ
操作符。eslint: no-delete-var
var name delete name // ✗ avoid
eslint: no-dupe-args
function sum (a, b, a) { // ✗ avoid // ... } function sum (a, b, c) { // ✓ ok // ... }
eslint: no-dupe-class-members
class Dog { bark () {} bark () {} // ✗ avoid }
eslint: no-dupe-keys
var user = { name: 'Jane Doe', name: 'John Doe' // ✗ avoid }
công tắc
语句无重复 trường hợp
从句。eslint: no-duplicate-case
switch (id) { case 1: // ... case 1: // ✗ avoid }
eslint: no-duplicate-imports
import { myFunc1 } from 'module' import { myFunc2 } from 'module' // ✗ avoid import { myFunc1, myFunc2 } from 'module' // ✓ ok
eslint: no-empty-character-class
const myRegex = /^abc[]/ // ✗ avoid const myRegex = /^abc[a-z]/ // ✓ ok
eslint: no-empty-pattern
const { a: {} } = foo // ✗ avoid const { a: { b } } = foo // ✓ ok
eval()
.eslint: no-eval
eval( "var result = user." + propName ) // ✗ avoid var result = user[propName] // ✓ ok
nắm lấy
语句中不要对错误对象重新赋值。eslint: no-ex-assign
try { // ... } catch (e) { e = 'new value' // ✗ avoid } try { // ... } catch (e) { const newVal = 'new value' // ✓ ok }
eslint: no-extend-native
Object.prototype.age = 21 // ✗ avoid
.bind()
.eslint: no-extra-bind
const name = function () { getName() }.bind(user) // ✗ avoid const name = function () { this.getName() }.bind(user) // ✓ ok
eslint: no-extra-boolean-cast
const result = true if (!!result) { // ✗ avoid // ... } const result = true if (result) { // ✓ ok // ... }
eslint: no-extra-parens
const myFunc = (function () { }) // ✗ avoid const myFunc = function () { } // ✓ ok
công tắc
语句使用 phá vỡ
,避免运行到下一个 trường hợp
.eslint: no-fallthrough
switch (filter) { case 1: doSomething() // ✗ avoid case 2: doSomethingElse() } switch (filter) { case 1: doSomething() break // ✓ ok case 2: doSomethingElse() } switch (filter) { case 1: doSomething() // fallthrough // ✓ ok case 2: doSomethingElse() }
eslint: no-floating-decimal
const discount = .5 // ✗ avoid const discount = 0.5 // ✓ ok
eslint: no-func-assign
function myFunc () { } myFunc = myOtherFunc // ✗ avoid
eslint: no-global-assign
window = {} // ✗ avoid
eval()
.eslint: no-implied-eval
setTimeout("alert('Hello world')") // ✗ avoid setTimeout(function () { alert('Hello world') }) // ✓ ok
eslint: no-inner-declarations
if (authenticated) { function setAuthUser () {} // ✗ avoid }
RegExp
构造器不使用非法的正则表达式字符串。eslint: no-invalid-regexp
RegExp('[a-z') // ✗ avoid RegExp('[a-z]') // ✓ ok
eslint: no-irregular-whitespace
function myFunc () /**/{} // ✗ avoid
__iterator__
.eslint: no-iterator
Foo.prototype.__iterator__ = function () {} // ✗ avoid
eslint: no-label-var
var score = 100 function game () { score: 50 // ✗ avoid }
eslint: no-labels
label: while (true) { break label // ✗ avoid }
eslint: no-lone-blocks
function myFunc () { { // ✗ avoid myOtherFunc() } } function myFunc () { myOtherFunc() // ✓ ok }
eslint: no-mixed-spaces-and-tabs
eslint: no-multi-spaces
const id = 1234 // ✗ avoid const id = 1234 // ✓ ok
eslint: no-multi-str
const message = 'Hello \ world' // ✗ avoid
mới
.eslint: no-new
new Character() // ✗ avoid const character = new Character() // ✓ ok
Function
构造器。eslint: no-new-func
var sum = new Function('a', 'b', 'return a + b') // ✗ avoid
Sự vật
构造器。eslint: no-new-object
let config = new Object() // ✗ avoid
new require
.eslint: no-new-require
const myModule = new require('my-module') // ✗ avoid
Biểu tượng
构造器。eslint: no-new-symbol
const foo = new Symbol('foo') // ✗ avoid
eslint: no-new-wrappers
const message = new String('hello') // ✗ avoid
eslint: no-obj-calls
const math = Math() // ✗ avoid
eslint: no-octal
const num = 042 // ✗ avoid const num = '042' // ✓ ok
eslint: no-octal-escape
const copyright = 'Copyright \251' // ✗ avoid
__dirname
Và __filename
不用于字符串拼接。eslint: no-path-concat
const pathToFile = __dirname + '/app.js' // ✗ avoid const pathToFile = path.join(__dirname, 'app.js') // ✓ ok
__proto__
,应使用 getPrototypeOf
.eslint: no-proto
const foo = obj.__proto__ // ✗ avoid const foo = Object.getPrototypeOf(obj) // ✓ ok
eslint: no-redeclare
let name = 'John' let name = 'Jane' // ✗ avoid let name = 'John' name = 'Jane' // ✓ ok
eslint: no-regex-spaces
const regexp = /test value/ // ✗ avoid const regexp = /test {3}value/ // ✓ ok const regexp = /test value/ // ✓ ok
eslint: no-return-assign
function sum (a, b) { return result = a + b // ✗ avoid } function sum (a, b) { return (result = a + b) // ✓ ok }
eslint: no-self-assign
name = name // ✗ avoid
esint: no-self-compare
if (score === score) {} // ✗ avoid
eslint: no-sequences
if (doSomething(), !!test) {} // ✗ avoid
eslint: no-shadow-restricted-names
let undefined = 'value' // ✗ avoid
eslint: no-sparse-arrays
let fruits = ['apple',, 'orange'] // ✗ avoid
eslint: no-tabs
eslint: no-template-curly-in-string
const message = 'Hello ${name}' // ✗ avoid const message = `Hello ${name}` // ✓ ok
super()
必须在访问 cái này
之前调用。eslint: no-this-before-super
class Dog extends Animal { constructor () { this.legs = 4 // ✗ avoid super() } }
ném
应当抛出一个 Lỗi
sự vật.eslint: no-throw-literal
throw 'error' // ✗ avoid throw new Error('error') // ✓ ok
eslint: no-trailing-spaces
không xác định
.eslint: no-undef-init
let name = undefined // ✗ avoid let name name = 'value' // ✓ ok
eslint: no-unmodified-loop-condition
for (let i = 0; i < items.length; j++) {...} // ✗ avoid for (let i = 0; i < items.length; i++) {...} // ✓ ok
eslint: no-unneeded-ternary
let score = val ? val : 0 // ✗ avoid let score = val || 0 // ✓ ok
trở lại
, ném
, Tiếp tục
, phá vỡ
语句后面不要有代码。eslint: no-unreachable
function doSomething () { return true console.log('never called') // ✗ avoid }
Cuối cùng
语句块无流程控制语句。eslint: no-unsafe-finally
try { // ... } catch (e) { // ... } finally { return 42 // ✗ avoid }
TRONG
操作符的左操作数不要使用 !
.eslint: no-unsafe-negation
if (!key in obj) {} // ✗ avoid
.call()
Và .apply()
.eslint: no-useless-call
sum.call(null, 1, 2, 3) // ✗ avoid
eslint: no-useless-computed-key
const user = { ['name']: 'John Doe' } // ✗ avoid const user = { name: 'John Doe' } // ✓ ok
eslint: no-useless-constructor
class Car { constructor () { // ✗ avoid } }
eslint: no-useless-escape
let message = 'Hell\o' // ✗ avoid
eslint: no-useless-rename
import { config as config } from './config' // ✗ avoid import { config } from './config' // ✓ ok
eslint: no-whitespace-before-property
user .name // ✗ avoid user.name // ✓ ok
với
语句。eslint: no-with
with (val) {...} // ✗ avoid
eslint: object-property-newline
const user = { name: 'Jane Doe', age: 30, username: 'jdoe86' // ✗ avoid } const user = { name: 'Jane Doe', age: 30, username: 'jdoe86' } // ✓ ok const user = { name: 'Jane Doe', age: 30, username: 'jdoe86' } // ✓ ok
eslint: padded-blocks
if (user) { // ✗ avoid const name = getName() } if (user) { const name = getName() // ✓ ok }
eslint: rest-spread-spacing
fn(... args) // ✗ avoid fn(...args) // ✓ ok
eslint: semi-spacing
for (let i = 0 ;i < items.length ;i++) {...} // ✗ avoid for (let i = 0; i < items.length; i++) {...} // ✓ ok
eslint: space-before-blocks
if (admin){...} // ✗ avoid if (admin) {...} // ✓ ok
eslint: space-in-parens
getName( name ) // ✗ avoid getName(name) // ✓ ok
eslint: space-unary-ops
typeof!admin // ✗ avoid typeof !admin // ✓ ok
eslint: spaced-comment
//comment // ✗ avoid // comment // ✓ ok /*comment*/ // ✗ avoid /* comment */ // ✓ ok
eslint: template-curly-spacing
const message = `Hello, ${ name }` // ✗ avoid const message = `Hello, ${name}` // ✓ ok
isNaN()
nghiên cứu NaN
.eslint: use-isnan
if (price === NaN) { } // ✗ avoid if (isNaN(price)) { } // ✓ ok
loại của
必须跟合法的字符串比较。eslint: valid-typeof
typeof name === 'undefimed' // ✗ avoid typeof name === 'undefined' // ✓ ok
eslint: wrap-iife
const getName = function () { }() // ✗ avoid const getName = (function () { }()) // ✓ ok const getName = (function () { })() // ✓ ok
yield*
của *
前后要有一个空格。eslint: yield-star-spacing
yield* increment() // ✗ avoid yield * increment() // ✓ ok
eslint: yoda
if (42 === age) { } // ✗ avoid if (age === 42) { } // ✓ ok
eslint: semi
window.alert('hi') // ✓ ok window.alert('hi'); // ✗ avoid
(
, [
, “` 开始行。这是省略分号时唯一的陷阱。standard 会保护你不落入陷阱。eslint: no-unexpected-multiline
// ✓ ok ;(function () { window.alert('ok') }()) // ✗ avoid (function () { window.alert('ok') }())
// ✓ ok ;[1, 2, 3].forEach(bar) // ✗ avoid [1, 2, 3].forEach(bar)
// ✓ ok ;`hello`.indexOf('o') // ✗ avoid `hello`.indexOf('o')
提示:如果你经常这样写代码,你可能是过于聪明了。
不鼓励过于聪明的简写,表达式应尽可能清晰且容易阅读:
不要这样:
;[1, 2, 3].forEach(bar)
这样更好:
var nums = [1, 2, 3] nums.forEach(bar)
现在所有流行的代码压缩器都是通过 AST 压缩,因此它们在处理没有分号的 JavaScript 代码时没有问题(因为 JavaScript 不是必须使用分号)。
[依赖自动插入分号机制]的代码是非常安全的,是完全合法的 JavaScript 代码,各浏览器都能正确解析;Closure compiler、yuicompressor、packer 及 jsmin 都能正确压缩。没有任何性能影响。
抱歉,我不是向你说教,这个语言的社区领导者在撒谎,并且害怕告诉你真相。真是羞耻。我建议,先了解 JavaScript 语句是如何结束的以及什么情况不会结束,之后你可以写出漂亮的代码。
一般来说,\N
结束语句,除非:
.
hoặc ,
结束。--
hoặc ++
,这时它将递减或递增下一个 token。for()
, while()
, LÀM
, if()
, 或 khác
,并且没有 {
.[
, (
, +
, *
, /
, -
, ,
, .
,或者是二进制操作符——它们只能出现在一个表达式的两个操作数之间。第一条显而易见。像这些情况:JSON 或括号内有 \N
字符;一个 khác nhau
多行声明,每行以 ,
结束,即使是 JSLint 都没问题。
第二条很怪。我从没有看到这种写法 i\n++\nj
。事实上,它被解析为 i; ++j
, thay vì i++; j
.
第三条很好理解。if (x)\ny()
bình đẳng if (x) { y() }
。这个语句直到遇到一个语句块或语句才结束。
;
是一个合法的 JavaScript 语句,所以 if(x);
bình đẳng if(x){}
或 “If x, do nothing.” 。这更多用于循环,这时循环测试同时也是更新函数。不常见,但不是没听过。
第四条通常是那些因循守旧的人提到的情况:“不,你需要分号!”。但是,事实证明,如果你的意思是这些行不是上一行的连续行,那么在这些行之前加上分号非常容易。例如
foo(); [1,2,3].forEach(bar);
可以这么写:
foo() ;[1,2,3].forEach(bar)
这么做的好处是,一旦你习惯了以 (
hoặc [
开始的行没有分号,你会很容易注意到行首的分号。
结束引用 “An Open Letter to JavaScript Leaders Regarding Semicolons”
Phụ thuộc vào Ivan Yan 翻译,译文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议,意见反馈.
更多关于分号的讨论:
Tôi đang tìm hiểu tất cả các công nghệ cần thiết để xây dựng Ứng dụng trang đơn (SPA). Tóm lại, tôi muốn triển khai ứng dụng của mình dưới dạng các lớp riêng biệt, trong đó giao diện người dùng giao tiếp với giao diện quản trị chỉ bằng các dịch vụ web API (json qua socket.io). Phần đầu về cơ bản là
Khi tôi nhìn thấy ngày được lưu trữ trong cơ sở dữ liệu của mình. Đây là điều bình thường. Ngày tháng và thời gian chỉ có vậy. Nhưng khi tôi chạy yêu cầu get để lấy dữ liệu. Định dạng này khác với định dạng được lưu trữ trong cơ sở dữ liệu. Tại sao điều này lại xảy ra? Câu trả lời hay nhất tôi nghĩ bạn có thể
Hiện tại, câu hỏi này không phù hợp với định dạng Hỏi & Đáp của chúng tôi. Chúng tôi mong đợi câu trả lời được hỗ trợ bởi các sự kiện, tài liệu tham khảo hoặc chuyên môn, nhưng câu hỏi này có thể gây ra tranh luận, tranh cãi, thăm dò ý kiến hoặc thảo luận mở rộng. Nếu bạn cảm thấy vấn đề này có thể được cải thiện và có thể mở lại, hãy truy cập
Tôi đang cố gắng triển khai một số mã bằng backbone.js và hogan.js (http://twitter.github.com/hogan.js/) Hogan.js được phát triển
Tôi đang tạo một ứng dụng web bằng Backbone.js, Node.js và Express.js và tôi muốn thêm chức năng cho người dùng (đăng nhập, đăng xuất, hồ sơ, hiển thị nội dung liên quan đến người dùng). Tôi dự định sử dụng Passport
đóng cửa. Câu hỏi này cần được hỏi một cách tập trung hơn. Hiện tại không chấp nhận câu trả lời. Bạn có muốn cải thiện điều này không? Cập nhật câu hỏi để tập trung vào một vấn đề duy nhất bằng cách chỉnh sửa bài đăng này. Đã đóng 8 năm trước. Cải thiện câu hỏi này
Tôi đang cố gắng tải dữ liệu trong NodeJS rồi chuyển nó sang ExpressJS để hiển thị biểu đồ d3 trên trình duyệt. Tôi biết tôi có thể tải dữ liệu theo cách này - https://github.com/mbostock/q
Trong node.js, tôi thấy có 3 tên tệp giống nhau để mô tả điểm vào chính của ứng dụng: Khi sử dụng gói express-generator, tệp app.js được tạo làm điểm vào chính cho ứng dụng được tạo. Bởi n
Gần đây tôi có cơ hội xem lớp học tuyệt vời của John Papa về cách xây dựng ứng dụng trang đơn. Tôi muốn nó. Nó liên quan đến mọi khía cạnh của ứng dụng phía máy chủ và phía máy khách. Tôi thích phía khách hàng hơn. Trong quá trình triển khai, ông Papa có lớp sau ở phía máy khách:
Hiện tại, câu hỏi này không phù hợp với định dạng Hỏi & Đáp của chúng tôi. Chúng tôi mong đợi câu trả lời được hỗ trợ bởi các sự kiện, tài liệu tham khảo hoặc chuyên môn, nhưng câu hỏi này có thể gây ra tranh luận, tranh cãi, thăm dò ý kiến hoặc thảo luận mở rộng. Nếu bạn cảm thấy vấn đề này có thể được cải thiện và có thể mở lại, hãy truy cập
Tôi là người mới học đồ họa và cần trợ giúp để hiểu chức năng của nhiều thư viện javascript 2D. . . Tôi nhận được gì từ Pixi.js mà tôi không nhận được từ các thư viện dựa trên Canvas như Konva? Tôi đến từ Konva
Tôi đang cố gắng xây dựng một số mã ÍT HƠN (thông qua ember-cli-less) vào một tệp CSS. 1) https://almsaeedstudio.com/ Tệp AdminLTE LESS 2) Bo
Đang cố gắng xem tất cả các phiên của tất cả người dùng đã đăng nhập trong Express Passport và hy vọng cũng có thể xem được người dùng hiện đang đăng nhập. Cách tốt nhất và nhanh nhất là gì? Tôi đang nghĩ có lẽ tôi có thể làm điều này khi đăng nhập và đưa cơ sở dữ liệu mô hình người dùng "trực tuyến"
Tôi có một ứng dụng React nhưng tôi cần chạy một số mã js phía máy khách sau khi một thành phần tải xong. Sau khi hàm render hoàn tất và được tải, cách tốt nhất để chạy js tương tác với DOM là gì, chẳng hạn như $('div').mixItUp() . Phải
Vui lòng cho tôi biết cách tải tệp lên máy chủ express.js phía máy khách bằng bodyparser.raw() // ... onFilePicked(file) { const url = 'upload/a
Tôi đang cố gắng di chuyển từ Grunt sang Gulp. Dự án chạy tốt trên Grunt, vậy nên có lẽ tôi đã làm sai điều gì đó trong Gulp. Mọi tác vụ khác đều hoạt động ngoại trừ tập lệnh. Tôi mệt mỏi khi phải thêm và chú thích các phần rồi. Tôi liên tục nhận được những điều bất ngờ
Tôi đang cố gắng đổi tên trang web của mình. Không tìm thấy nơi tôi có thể đặt tiêu đề hoặc tên ứng dụng. Câu trả lời hay nhất Bạn có thể tạo bất kỳ tệp nào trong thư mục config/, ví dụ config/app.js với nội dung sau: module.expor
Sau nhiều năm phát triển PHP/MySQL trên máy chủ, tôi đang cố gắng khám phá các công nghệ mới để xây dựng các ứng dụng web hiện đại. Tôi đang cố gắng sắp xếp tất cả nội dung JavaScript và nếu tôi hiểu rõ, một giải pháp hiệu quả có thể là phục vụ
Tôi mới làm quen với Nodejs. Tôi có app.js và index.js trong thư mục tuyến đường. Tôi có một ứng dụng.use(multer....). Tôi cũng đã định nghĩa app.post('filter-re
Tôi đang sử dụng mẫu Angular-seed để xây dựng ứng dụng của mình. Ban đầu, tôi đặt toàn bộ mã JavaScript của mình vào một tệp, main.js. Tệp này chứa khai báo mô-đun, bộ điều khiển, chỉ thị, bộ lọc và
Tôi là một lập trình viên xuất sắc, rất giỏi!