澳门威利斯人_威利斯人娱乐「手机版」

来自 威利斯人娱乐 2019-08-24 09:20 的文章
当前位置: 澳门威利斯人 > 威利斯人娱乐 > 正文

帮你提升代码质量,通俗易懂版

天天学一些新东西能够让三个悟性之人走上不轻松之路。而作为开垦职员,不断的求学新东西则是我们事业的一部分, 不论这一个新东西是或不是缘于积极的上学经历。

一、初始Node.js

本片文章,在前人的根底上,加上自身的知情,解释一下JavaScript的代码实施进度,顺路介绍一下实施景况和闭包的连锁概念。

  在本篇教程中,小编将提议部分注重的 JavaScript 最棒施行,让您不必去用别的一种辛苦的方法来打听它们。筹划好去提高你的代码吧!

1.Node.js是什么?

分成两部分。第一有个别是询问实施处境的相干概念,第二有的是透超过实际际代码掌握具体实行进度中施行碰到的切换。

图片 1

深入显出的演说:

  Node.js = Javascript 本地/服务器文件读写删除等成效。

  简来讲之 Node.js 正是运维在服务端的 JavaScript。试行在浏览器上的时候成为JavaScript,实施在服务器上的时候叫做Node.js。当然写法是有分别的。

  JavaScript受限于浏览器沙盒模式,只好运转在浏览器中。而Node.js扩充了JavaScript的成效,使其能够运维在该地/服务器。

  它不是后端语言,可是足以用来写后端程序。

实行情状的分类

  • 1.全局推行意况是JS代码早先运维时的暗许意况(浏览器中为window对象)。全局实行景况的变量对象始终都是职能域链中的最终二个对象。
  • 2.函数推行情况当有些函数被调用时,会先创造三个执行景况及相应的功力域链。然后使用arguments和别的命名参数的值来起初化实施蒙受的变量对象。
  • 3.采纳eval()实践代码

尚未块级成效域(本文不涉及ES6中let等概念)

 1. 幸免对全局作用域的污染

  评释变量是一件很遗闻业。有时候正是你不想这么做,但也可以有望会定义出全局变量。在当今的浏览器中,全局变量都被寄放在 window 对象中。而因为有众多的东西都在十分里面,所以你有极大大概把一部分私下认可值都给覆盖掉了。

  借令你有一个 HTML 文件,里面包蕴了壹个 <script> 标志,而以此标志内含 (或许通过援用四个 JavaScript 文件而加载) 如下内容:

var foo = 42;
console.log(foo);

  这段代码很醒目会让决定台输出 42。可是因为代码而不是放到二个函数里面去推行的,由此其实践的上下文就能够是大局的丰硕。由此,变量就能被增大到 window 对象上。那就表示 window.foo 的值也会是 42。

  那样是挺危急的,因为您能够把早就存在的全局变量给覆盖掉:

function print () {
  // do something
}
print();

  当推行 window.print (恐怕只是试行 print) 的时候, 它不会展开打字与印刷弹窗,因为大家早已将原生的打字与印刷弹窗逻辑给覆盖掉了。

  化解那些主题素材的方案非凡轻易; 大家必要三个会在概念后随即被调用到的闭包函数, 如下所示:

// Declare an anonymous function
(function () {
  var foo = 42;
  console.log(window.foo);
  // → undefined
  console.log(foo);
  // → 42
})();
//^ and call it immediately

  只怕您也能够挑选将 window 以及别的全局的事物(举个例子document)都用作参数字传送给这么些函数(那样做也说不定对质量会持有提高):

(function (global, doc) {
 global.setTimeout(function () {
   doc.body.innerHTML = "Hello!";
 }, 1000);
})(window, document);

  因此你得使用闭包函数来制止创设出怎么样全局的东西来。注意在那边因为要留神于代码本人,所以笔者不会在后头的代码片段中运用闭包函数。

  提示: browserify 是另外一种防止成立全局变量的诀要。它利用了你在 Node.js 一样会用到的 require 函数的措施。

  顺便说一下, Node.js 会自动将你的文书封装进函数里面。它们看起来先下边那样:

(function (exports, require, module, __filename, __dirname) {
// ...

  因而,假若您感觉 require 函数式全局的,好呢,并非。它独自正是贰个函数的参数。

特性: 

  Node.js 是三个依据Chrome JavaScript 运营时确立的三个平台。

  Node.js是三个事件驱动I/O服务端JavaScript情状,基于Google的V8引擎,V8引擎推行Javascript的进程十分的快,品质相当好。

 

施行上下文的咬合

进行情状(execution context,EC)或称为推行上下文,是JS中叁个极为首要的概念。当JavaScript代码实行时,会踏向区别的实践上下文,而种种实践上下文的构成,基本如下:

图片 2

  • 变量对象(Variable object,VO): 变量对象,即含有变量的指标,除了大家不可能访问它外,和平时对象没怎么界别
  • [[Scope]]本性:数组。功效域链是一个由变量对象组成的领头结点的单向链表,其重点功能便是用来张开变量查找。而[[Scope]]属性是二个针对性这一个链表头节点的指针。
  • this: 指向多少个条件指标,注意是三个对象,并且是二个清淡无奇对象,并不是一个施行情状。

若干执行上下文仲构成八个实施上下文栈(Execution context stack,ECS)。而所谓的进行上下文栈,例如,例如上边的代码

var a = "global var";function foo(){ console.log;}function outerFunc(){ var b = "var in outerFunc"; console.log; function innerFunc(){ var c = "var in innerFunc"; console.log; } innerFunc();}outerFunc()

代码首先步入Global Execution Context,然后千家万户进来outerFunc,innerFunc和foo的施行上下文,实施上下文栈就能够表示为:

图片 3

试行全局代码时,会发出三个实施上下文意况,每回调用函数都又会生出实施上下文情形。当函数调用实现时,这些上下文景况以及中间的数量都会被解决,再另行再次回到全局上下文处境。处于活动状态的实践上下文情况只有贰个。

图片 4

当一段JS代码实践的时候,JS解释器会通过五个阶段去发生贰个EC

  • 成立阶段(当函数被调用,然而伊始推行函数内部代码此前)
    • 创造变量对象VO
    • 设置[[Scope]]属性的值
    • 设置this的值
    • 激活/代码试行阶段
  • 早先化变量对象,即设置变量的值、函数的援用,然后解释/实行代码。

  你领悟呢?

  因为 window 对象饱含了具有的全局变量,又因为它自个儿也是大局的,因此window 本身内部也引用了它协调:

window.window.window
// => Window {...}

  那是一个人 window 对象是一个巡回援用对象。上面体现了何等成立这样的三个指标:

// Create an object
var foo = {};
// Point a key value to the object itself
foo.bar = foo;
// The `foo` object just became a circular one:
foo.bar.bar.bar.bar
// → foo

  也许,为了显得你对 JavaScript 的无比的喜爱之情,你能够当回头痛友,代码如下:

图片 5

  是的,你能够大约没完没了(也可能有不小希望会等到浏览器崩溃)的进展这一个指标。

2.Node.js的安装

在官方网站下载长效帮助版本(LTS)就可以。能够应用 node -v 查看安装的node版本。

 

创立变量对象VO进度

  • 1.基于函数的参数,创建并开端化arguments object
  • 2.围观函数内部代码,查找函数注解(function declaration)
    • 对此持有找到的函数评释,将函数名和函数援引存入VO中
    • 假设VO中一度有同名函数,那么就张开覆盖
  • 3.围观函数内部代码,查找变量注解(Variable declaration)
    • 对此全数找到的变量注解,将变量名存入VO中,并伊始化为undefined
    • 一旦变量名跟已经宣示的形参或函数相同,则什么也不做

注:步骤2和3也叫做申明提高(declaration hoisting)

咱俩举个例子表达,借使大家有几个js文件,内容如下:

var global_var1 = 10;function global_function1(parameter_a){ var local_var1 = 10 ; return local_var1   parameter_a   global_var1;}var global_sum = global_function1;alert(global_sum);

下边大家来一步一步表达解释器是何等施行这段代码的:

 2. 好的 use strict 使用习于旧贯

  要严刻使用 use strict! 那然则正是在您的代码中加了一行,给你的剧本扩张越来越多的小把戏。

  例如:

// This is bad, since you do create a global without having anyone to tell you
(function () {
   a = 42;
   console.log(a);
   // → 42
})();
console.log(a);
// → 42

  使用 use strict, 你就足以取获得越来越多一点的错误音信:

(function () {
   "use strict";
   a = 42;
   // Error: Uncaught ReferenceError: a is not defined
})();

  你大概想通晓为什么能够将 "use strict" 放在封装函数的外侧。那真的是足以的,不过如此它就能够被使用到全局。那还不是太坏,然而如若有代码是来自于另外的库,只怕你要把具有的事物都打包到一个文件之中去的话,这样做就能够有影响的。

3.node.js索要重视命令行分界面来运转

1.开立全局上下文

先是,在解释器眼中,global_var1global_sum名叫全局变量,因为它们不属于别的函数。local_var1称得上局地变量,因为它定义在函数global_function1内部。global_function1叫做全局函数,因为它并未有概念在任何函数内部。

接下来,解释器初步扫描这段代码,为施行这段代码做了一部分备选干活——创制了三个大局上下文

全局上下文,能够把它看做贰个JavaScript对象,姑且称之为global_context。那些指标是解释器创立的,当然也是由解释器使用。(大家的JavaScript代码是接触不到那些指标的)

global_context对象大致是其同样子的:

global_context = { Variable_Object :{......}, Scope :[......], this :{......}}

能够见见,global_context有四个属性

  • Variable_Object{global_var1:undefinedglobal_function1:函数 global_function1的地址global_sum:undefined}

    解释器在VO中著录了变量全局变量global_var1global_sum,但它们的值今后是undefined的,还记下了大局函数global_function1,不过从未记录局地变量local_var1。VO的原型是Object.prototype

  • Scope数组中的内容如下:

     [ global_context.Variable_Object ]
    

    咱俩来看,Scope数组中唯有一个对象,正是方今刚成立的对象VO。

  • this

    this的值未来是undefined

global_context对象被解释器压入贰个栈中,不妨叫那么些栈为context_stack。现在的context_stack是这样的:

图片 6

创建出global_context后,解释器又悄悄干了一件事,它给global_function1设置了一个里面属性,也叫scope,它的值正是global_context中的scope!也正是说,未来:

global_function1.scope === [ global_context.Variable_Object ];

作者们获得不到global_function1的scope属性的,独有解释器本人能获取到。

 3. 严酷相等

  那个比较简便。借使您在 JavaScript 中 (像其余的编制程序语言中这样)使用 == 来相比较 a 和 b,或者会发掘其运营的措施有一点怪: 假让你有一个字符串和五个数字如下,它们会相等 (==):

"42" == 42
// → true

  对于某个显著的缘故 (比方验证操作), 最棒便是选用严峻等于(===):

"42" === 42
// → false

  1)node的调整台形式

  在极端中输入 node能够进去node的调控台情势,踏入之后命令行(终端)的标记会由$变为>,代表已经步入node的调整台方式。三个小例子:

图片 7

2.逐行试行代码

解释器在开创了全局上下文后,就从头实行这段代码了。

var global_var1 = 10;

解释器会把VO中的global_var1属性的值设为10。未来global_context对象产生了如此:

global_context = { Variable_Object :{ global_var1:10, global_function1:函数 global_function1的地址, global_sum:undefined }, Scope :[ global_context.Variable_Object ], this :undefined}

解释器继续实施大家的代码,它蒙受了注解式函数global_function1,由于在开立global_context对象时,它就早就记录好了该函数,所以未来它怎么也不用做。

var global_sum = global_function1;

解释器看到,大家在这里调用了函数global_function1(解释器已经提前在global_context的VO中著录下了global_function1,所以它驾驭我们这里是八个函数调用),并且传入了二个参数10,函数的归来结果赋值给了全局变量global_sum

解释器并从未应声实行函数中的代码,因为它要为函数global_function1创制一个极度的context,我们叫它执行上下文(execute_context)吧,因为每当解释器要施行八个函数时,都会成立叁个近乎的context。

execute_context也是贰个指标,何况与global_context还很像,下边是它里面包车型大巴剧情:

execute_context = { Variable_Object :{ parameter_a:10, local_var1:undefined, arguments:[10] }, Scope :[execute_context.Variable_Object, global_context.Variable_Object ], this :undefined}

大家看到,execute_context与global_context相比较,有以下几点变化:

  • VO
    • 率先记录了函数的款式参数parameter_a,并且给它赋值10,那一个10就是大家调用函数时传递步向的。
    • 接下来记录了函数体内的片段变量local_var1,它的值照旧undefined。
    • 下一场是多少个arguments属性,它的值是叁个数组,里面唯有贰个10。

你大概可疑,不是一度在parameter_a中著录了参数10了吗,为啥解释器还要搞多少个arguments,再来记录三次呢?原因是假如大家这么调用函数:

global_function1;

在JavaScript中是不违纪的。此时VO中的arguments会形成那样:

arguments:[10,20,30]

parameter_a的值如故10。可知,arguments是特意记录咱们传进去的具有参数的。

  • Scope

Scope属性依旧是多个数组,只然则里面包车型客车因素多了个execute_context.Variable_Object,而且排在了global_context.Variable_Object前面。

解释器是依靠什么准则决定Scope中的内容的吧?答案非常轻便:

execute_context.Scope = execute_context.Variable_Object   global_function1.scope。

也等于说,每当要实践叁个函数时,解释器都会将施行上下文(execute_context)中Scope数组的首先个因素设为该推行上下文(execute_context)的VO对象,然后收取函数成立时保留在函数中的scope属性(本文中则是global_function1.scope),将其增多到推行上下文(execute_context)Scope数组的后面。

我们领会,global_function1是在global_context下创制的,成立的时候,它的scope属性被设置成了global_context的Scope,里面只有多少个global_context.Variable_Object,于是这几个指标被增加到execute_context.Scope数组中execute_context.Variable_Object对象后边。

别的贰个函数在开创时,解释器都会把它所在的试行上下文或许全局上下文的Scope属性对应的数组设置给函数的scope属性,这些性格是函数“与生俱来”的。

  • thisthis的值此时还是是undefined的(但不一样的解释器可能有两样的赋值)

解释器为函数global_function1创建好了execute_context后,会把那些上下文对象压入context_stack中,所以,现在的context_stack是这么的:

图片 8

 4. 行使 && 和 || 来创造点小把戏

  根你供给做的事务,你能够选用逻辑操作符来让代码更简约。

  2)引进外界代码文件

  ① 假诺要在调控台推行某些外界代码文件,比方推行index.js,大家能够用cd命令步入该目录之后输入 node index.js 

  ② 假使把其他的js文件引进到当前的js文件中,代码如下:

   var x = require ('./index2')  (引进当前目录下的index2.js到当下文件)

  control c 是脱离当前程序的组合键,大家得以选取 control c 来退出node调节台形式。

 

安不忘危推行函数内的代码

搞好了备选干活,解释器初阶实行函数里面包车型客车代码了,此时我们称函数是在实施上下文中运作的。

var local_var1 = 10 ;

它的拍卖措施极粗略,将execute_context的VO中的local_var1赋值为10。这点与在global_context下试行的变量赋值语句的处理同样。此时的execute_context形成那样:

execute_context = { Variable_Object :{ parameter_a:10, local_var1:10, //为local_var1赋值10 arguments:[10] }, Scope :[execute_context.Variable_Object, global_context.Variable_Object ], this :undefined}

return local_var1   parameter_a   global_var1;
  • 解释器进一步观看语句,开采那是一个回到语句,于是它开首谋算return 后边的表达式的值。
  • 在表明式中它首先遭遇了变量local_var1,它首先在execute_context的Scope中相继查找,在首先个因素execute_context的VO发现了local_var1,并且知道它的值是10
  • 接下来解释器继续发展,碰着了变量parameter_a,它画虎类犬,在execute_context的VO中窥见了parameter_a,况且明确它的值是10。
  • 随之发掘 global_var1,解释器从execute_context的Scope第一个成分execute_context.VO中寻觅,未有意识global_var1。继续翻看Scope数组的第2个因素,即global_context.VO,开采况兼规定了它的值为10。
  • 于是乎,解释器将多少个变量值相加获得了30,然后就回到了。
  • 此刻,解释器知道函数已经试行完了,那么它为这些函数创造的施行上下文也从没用了,于是,它将execute_context从context_stack中弹出,由于并未有其他对象引用着execute_context,解释器就把它销毁了。现在context_stack中又只剩下了global_context。
var global_sum = 30;

近些日子解释器又再次来到全局上下文中施行代码了,这时它要把30赋值给sum,方法就是更改global_context中的VO对象的global_sum品质的值。

alert(global_sum);

解释器继续上扬,境遇了语句alert(global_sum);很简短,就是发生二个弹窗,弹窗的从头到尾的经过正是global_sum的值30,当大家点击弹窗上的规定开关后,解释器知道,这段代码终于试行完了,它会打扫战地,把global_context,context_stack等能源总体销毁。

  取默许值

"" || "foo"
// → "foo"
undefined || 42
// → 42
// Note that if you want to handle 0 there, you need
// to check if a number was provided:
var a = 0;
a || 42
// → 42
// This is a ternary operator—works like an inline if-else statement
var b = typeof a === "number" ? a : 42;
// → 0

  不用拿 if 表明式来检查有个别事物是或不是为真正,你也能够差相当的少地那样做:

expr && doSomething();

// Instead of:


if (expr) {
   doSomething();
}

  假令你需求经过 doSomething(): 来决定回到的结果,那样做更酷:

function doSomething () {
   return { foo: "bar" };
}


var expr = true;


var res = expr && doSomething();
res && console.log(res);
// → { foo: "bar" }

  你可能不会偏向笔者在那上边的见识,但像自家说的这么抓牢在效果更白玉无瑕。假让你并不想像这么来对您的代码举办模糊,但其实那正是那一个JavaScript 简化器实际会做的作业。

  假设你来问我,作者会说这么做尽管让代码越发简明了,但照旧是可读的。

4.Node.js REPL(交互式解释器)

REPL 命令

  • ctrl c - 退出当前极端。

  • ctrl c 按下几回 - 退出 Node REPL。

  • ctrl d - 退出 Node REPL.

  • 向上/向下 键 - 查看输入的历史命令

  • tab 键 - 列出当前下令

  • .help - 列出利用命令

  • .break - 退出多行表达式

  • .clear - 退出多行表明式

  • .save filename - 保存当前的 Node REPL 会话到钦定文件

  • .load filename - 载入当前 Node REPL 会话的文本内容。

再遇闭包

现行反革命,知道了上下文,函数的scope属性的文化后,大家就能够开首学习闭包了。让大家将下面的js代码改成这么:

var global_var1 = 10;function global_function1(parameter_a){ var local_var1 = 10 ; function local_function1(parameter_b){ return parameter_b   local_var1   parameter_a   global_var1; } return local_function1 ;}var global_sum = global_function1;alert(global_sum;

这段代码与原来的代码最大的不等是,在global_function1里面,我们创设了二个函数local_function1,况兼将它看作重临值。

当解释器试行函数global_function1时,依旧会为它创设实践上下文,只可是此时execute_context.VO中多了叁个函数属性local_function1。然后,解释器就能起来试行global_function1中的代码。

我们直接从创建local_function1语句开首深入分析,看解释器是怎么实践的,闭包的全体地下就暗藏在里头。

当解释器在execute_context中实施创造local_function1时,它如故会将execute_context的Scope设置给函数local_function1的scope属性,也等于那样:

local_function1.scope = [ execute_context.Variable_Object, global_context.Variable_Object ]

然后,解释器蒙受了回去语句,把local_function1回去并赋值给了全局变量global_sum。此时global_context的VO中global_sum的值正是函数local_function1

此时,函数global_function1现已实行完了,解释器会怎么管理它的execute_context呢?

第一,解释器会把execute_context从context_stack中弹出,但并不把它完全销毁,而是保存了execute_context.Variable_Object对象,把它转移到了另一块堆内部存储器中。为何不销毁呢?因为还可能有对象援用着它呢。引用链如下:

图片 9

这表示什么吧?那注明,当global_function1终止再次回到后,它的款型参数parameter_a,局地变量local_var1以及部分函数local_function1都未有灭绝,还如故存在。那点,与面向对象的语言Java中的经验完全两样,这也是闭包难以领悟的有史以来所在。

下边大家的解释器继续实行语句alert(global_sum;alert参数是对函数global_sum的调用,global_sum的参数为10,大家领略函数global_sum的代码是那般的:

function local_function1(parameter_b){ return parameter_b   local_var1   parameter_a   global_var1;}

要实行那几个函数,解释器依旧会为它成立三个推行上下文,大家姑且称之为local_context2,这一个目的的剧情是这么的:

execute_context2 = { Variable_Object :{ parameter_b:10, arguments:[10] }, Scope :[execute_context2.Variable_Object, execute_context.Variable_Object, global_context.Variable_Object ], this :undefined}

这里大家第一看看Scope属性,它的率先个要素千真万确是execute_context2.Variable_Object,后边的要素是从local_function1.scope品质中收获的,它是在local_function1开创时所在的实行上下文的Scope属性决定的。

创建的execute_context2压入context_stack后,解释器开始实行语句

return parameter_b   local_var1   parameter_a   global_var1;

对于该句中多少个变量,解释器分明它们的值的法子还是的简练,先是在目前推行上下文(相当于execute_context2)的Scope的第一个因素中追寻,第一个找不到就在第贰个要素中查找,然后就是第四个,直至global_context.Variable_Object。

接下来,解释器就能将多个变量值相加后回到。弹出execute_context2,此时execute_context2已经远非指标引用着它,解释器就把它销毁了。

终极,alert函数会收到值40,然后发出叁个弹窗,弹窗的内容正是40。程序结束

轻便讲,当我们从函数global_function1中回到另二个函数local_function1时,由于local_function1scope特性中援用着为实行global_function1创建的execute_context.Variable_Object对象,导致global_function1在执行实现后,它的execute_context.Variable_Object目的并不会被回收,此时我们称函数local_function1是五个闭包,因为它除了是一个函数外,还保存着创设它的施行上下文的变量音讯,使得大家在调用它时,依旧能够访问那些变量。

函数将开创它的左右文中的VO对象密封包蕴在友好的scope属性中,函数就形成了二个闭包。从那个广阔的意思上的话,global_function1也得以称之为闭包,因为它的scope内部属性也暗含了创制它的全局上下文的变量音讯,相当于global_context.VO

 5. 对值的品类进行转账

  有三种艺术能够依附你的主见来开展中间转播。最常用的法门有如下那些:

// From anything to a number

var foo = "42";
var myNumber =  foo; // shortcut for Number(foo)
// → 42

// Tip: you can convert it directly into a negative number
var negativeFoo = -foo; // or -Number(foo)
// → -42

// From object to array
// Tip: `arguments` is an object and in general you want to use it as array
var args = { 0: "foo", 1: "bar", length: 2 };
Array.prototype.slice.call(args)
// → [ 'foo', 'bar' ]

// Anything to boolean
/// Non non p is a boolean p
var t = 1;
var f = 0;
!!t
// → true
!!f
// → false

/// And non-p is a boolean non-p
!t
// → false
!f
// → true

// Anything to string
var foo = 42;
""   foo // shortcut for String(foo)
// → "42"

foo = { hello: "world" };
JSON.stringify(foo);
// → '{ "hello":"world" }'

JSON.stringify(foo, null, 4); // beautify the things
// →
// '{
//    "hello": "world"
// }'

// Note you cannot JSON.stringify circular structures
JSON.stringify(window);
// ⚠ TypeError: JSON.stringify cannot serialize cyclic structures.

 

推荐小说

  • 教您步步为营领会JavaScript闭包(本篇小说脱胎于那篇小说)
  • 略知一二JS施行情况
  • 深刻驾驭JavaScript闭包和原型链

 6. 代码风格/风格指南

  在新的品种中要让具有的文书都遵照平等的代码风格。对于现成的档案的次序,就选择现成的代码风格, 除非你就只是决定要变一变它的风骨(提醒: 同你的合作就此展开一下讨论)。以致你要创制和记录您本人的代码风格,然后直接去依照它。

  现存的局地不一的代码风格如下:

  • Google JavaScript 风格指南

  • airbnb/javascript

  • ... 也还会有别的的部分

  • 自个儿的品格指南

二、NPM

 额外的平价小提醒:

  你应当牢记的其余一些关键的 JavaScript 最好推行正是那多少个能支援您对代码进行格式化的工具。上面是里面包车型地铁有的:

  • js-beautify: 美化你的代码

  • UglifyJS(2): 混淆/最小化你的代码

  • jshint: 检查评定 JavaScript 代码中的错误恐怕地下难点

  • jscs: 能够布署的体制指南检查测验器

  最终二个正是: 不要老是 console.log,要对您的代码举行调解。

  祝你编制程序高兴!

  原版的书文地址:

1.什么是NPM?  

NPM的完备是Node Package Manager,是会同NodeJS一齐安装的包管理和散发工具。

它能够很有益于地让JavaScript开荒者下载、安装、上传以及管理已经安装的包。

 

本文由澳门威利斯人发布于威利斯人娱乐,转载请注明出处:帮你提升代码质量,通俗易懂版

关键词: 澳门威利斯人 JavaScript 上下文 代码