肝了4.5万字,手把手带你玩转JavaScript(建议收藏)

Posted 极客江南

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了肝了4.5万字,手把手带你玩转JavaScript(建议收藏)相关的知识,希望对你有一定的参考价值。

江哥手把带你玩转 javascript 分为 5 期,大概 15 万字,建议点赞,关注,收藏,防止失联。

本期为第一期入门篇,4.5 万字。

什么是JavaScript?

  • JavaScript简称JS,是前端开发的一门脚本语言(解释型语言)

  • 解释型语言:程序执行之前,不需要对代码进行编译,在运行时边解析边执行的语言

  • 浏览器工作原理

  • 编译型语言:程序执行之前,需要一个专门的编译过程,把程序编译成机器语言的文件,比如exe文件

JavaScript作用

  • html 提供网页上显示的内容(结构)
  • CSS 美化网页(样式)
  • JavaScript 控制网页行为(行为)

JavaScript发展史

  • JavaScript起源于Netscape公司的LiveScript语言
    • 1994年网景公司发布历史上第一个比较成熟的浏览器(Navigator 0.9), 但是只能浏览不能***交互***
    • 1995年为了解决表单有效性验证就要与服务器进行多次地往返交互问题,网景公司录用Brendan Eich(布兰登·艾奇),他在 10 天内开发出 LiveScript 语言
    • 在 Netscape Navigator 2.0 即将正式发布前,Netscape 将LiveScript 更名为 JavaScript, 目的是为了蹭Java的热度
    • 所以Java和 JavaScript之间的关系就像老婆和老婆饼一样

参考文献


JavaScript组成

  • ECMAScript:JavaScript的语法标准
    • ECMA是European Computer Manufacturers Association的缩写,即欧洲计算机制造商协会
    • ECMAScript是ECMA制定的脚本语言的标准, 规定了一种脚本语言实现应该包含的基本内容
    • JavaScript是脚本语言的一种,所以JavaScript也必须遵守ECMAScript标准,包含ECMAScript标准中规定的基本内容
  • DOM(Document Object Model):JavaScript操作网页上的元素(标签)的API
  • BOM(Browser Object Model):JavaScript操作浏览器的部分功能的API

ECMAScript起源


JavaScript书写格式

  • 和CSS书写格式一样, JavaScript也有三种书写格式, 分别是"行内式"、“内嵌式”、“外链式”
  • 和CSS书写格式一样, JavaScript三种书写格式中也推荐大家使用"外链式", 遵守结构、样式、行为分离

  • 行内式格式(不推荐)
<div οnclick="alert('hello world');">我是div</div>

  • 内嵌式格式
</body>
... ...
<script type="text/javascript">
       alert("hello world");
</script>
</body>
  • 内嵌式注意点
  • 通常将js代码放在body的最后, 因为HTML是从上至下加载, 而js代码通常是给标签添加交互(操作元素), 所以需要先加载HTML, 否则如果执行js代码时HTML还未被加载, 那么js代码将无法添加交互(操作元素);
  • HTML页面中出现
<head>
    <script>
        window.onload = function () { // 必须添加这句
            alert("hello world");
        }
    </script>
</head>

  • 外链式格式
<script type="text/javascript" src="01-js书写格式.js"></script>
  • 外链式注意点
    • 外链式的script代码块中不能编写js代码, 即便写了也不会执行
<script type="text/javascript" src="01-js书写格式.js">
    alert("hello world"); // 不会被执行
</script>
  • 由于每次加载外链式的js文件都会发送一次请求, 这样非常消耗性能, 所以在企业开发中推荐将多个JS文件合成为一个JS文件,以提升网页的性能和加载速度

JS中的常见输出方式

  • 在控制台中显示内容
console.log("hello world3");
console.error("错误信息");
console.warn("警告信息");

  • 在浏览器弹窗中显示内容
alert("hello world");
prompt("请输入内容:");
confirm("你好吗?");
  • 在页面中显示内容
document.write("hello world2");
  • 注意点:
  • JS中严格区分大小写
alert("hello world"); // 正确 
Alert("hello world"); // 错误
  • 每一条JS语句以分号(;)结尾
  • 如果不写分号,浏览器会自动添加,但是会消耗一些系统资源
  • 并且有些时候浏览器会加错分号,所以在开发中分号必须写
  • JS中会忽略多个空格和换行
alert
(
"hello world"
);  

JS中的常见输出方式

  • 在浏览器弹窗中显示内容
alert("hello world");
prompt("请输入内容:");
confirm("你好吗?");
  • 在页面中显示内容
document.write("hello world2");
  • 在控制台中显示内容
console.log("hello world3");
console.error("错误信息");
console.warn("警告信息");

  • 注意点:
  • JS中严格区分大小写
alert("hello world"); // 正确 
Alert("hello world"); // 错误
  • 每一条JS语句以分号(;)结尾
  • 如果不写分号,浏览器会自动添加,但是会消耗一些系统资源
  • 并且有些时候浏览器会加错分号,所以在开发中分号必须写
  • JS中会忽略多个空格和换行
alert
(
"hello world"
);  

常量

  • 什么是常量?

  • 常量表示一些固定的数据,也就是不能改变的数据

  • 常量分类

    • 整型常量
      • 二进制(以0b开头; 例如0b1001,0b1010)
      • 十进制(9,-10,0)
      • 八进制(以0开头; 例如011, 012)
      • 十六进制(以0x开头; 0x10, 0x11)
    • 实型常量
      • 小数(3.14, 9.8)
    • 字符串常量
      • 使用单引号(’)或双引号(")括起来的一个或几个字符
    • 布尔值
      • 布尔常量只有两种状态:true或false
    • 特殊字符
      \\n 换行,相当于敲一下回车。
      \\t 跳到下一个tab位置,相当于按一下键盘上的tab键。 \\b 退格,相当于按一下backspace。
      \\r 回车。
      \\f 换页,光标移到到下页开头。
      \\\\ 输出\\字符,也就是在屏幕上显示一个\\字符。
      \\' 输出'字符,也就是在屏幕上显示一个'字符。
      \\" 输出"字符,也就是在屏幕上显示一个"字符。
      
  • 练习
    10.6、19.0、‘A’、“男”、“lnj”、294、true


变量

什么是变量?

  • 变量表示一些可以变化的数据。当一个数据的值需要经常改变或者不确定时,就应该用变量来表示
  • 例如:超市中的储物格就相当于一个变量, 里面可以存储各种不同的东西, 里面存储的东西也可以经常改变
  • 你去超市放东西到储物柜的格子中,他会给你一张纸条,你根据这个纸条才可以拿回自己的东西,储物柜的一格就是变量的内存空间,字条就是变量名,你拿和放就是修改变量名对应内存中的数据

如何定义变量?

  • 定义变量(声明变量), 任何变量在使用之前,必须先进行定义
  • 定义变量的目:在内存中分配一块存储空间给变量,方便以后存储数据。
  • 如果定义了多个变量,就会为这多个变量分别分配不同的存储空间。
  • 格式1: var 变量名称 ;
    var num;
    • 格式2: var 变量名称,变量名称;
        var num1, num2, num3;
      

如何使用变量?

  • 使用变量就是往变量里面存点东西或者取出变量中存储的内容;
  • 往变量中存储内容
var num;
num = 10;

注意:

  • 这里的等号 =,并不是数学中的“相等”,而是JavaScript语言中的赋值运算符,作用是将右边的常量10赋值给左边的变量num
  • 赋值的时候= 号的左侧必须是变量 (10 = num; 错误写法)
  • 规范:习惯将 = 的两侧 各加上一个 空格
  • 变量的初始化
  • 变量第一次赋值,可以称为“初始化”
  • 先定义,后初始化
    var num;
    num = 10;
    
  • 定义的同时进行初始化
    var num = 10;
    
  • 其它表现形式
      // 部分初始化
      var a, b, c = 10;
      // 完全初始化
      var a , b, c;
      a = b = c = 10;
    
  • 思考: 不初始化里面存储什么?
      var num;
      console.log(num); // undefined
      // 如果变量没有初始化, 里面存储的是undefined
    
  • 如何查看变量的值?

    var num;
    num = 10;
    console.log(num);
    
  • 如何修改变量值?

  • 利用等号(=)重新赋值即可,每次赋值都会覆盖原来的值
     var num;
     num = 10;
     num = 20;
     console.log(num); // 20
    
  • 变量之间的值传递
  • 可以将一个变量的值赋值给另一个变量
    var a = 10;
    var b = a;
    console.log(b); // 10
    

关键字和保留字

  • 什么是关键字?
  • 被JavaScript语言赋予了特殊含义的单词
  • 好比现实生活中110、120、119对我们又特殊含义一样, 在JavaScript也有一些对于JavaScript有特殊含义的单词,这些单词我们称之为关键字
  • 关键字在开发工具中会显示特殊颜色
  • 关键字不能用作变量名、函数名等
  • 关键字严格区分大小写, var和Var前者是关键字, 后者不是
关键字
breakdoinstanceoftypeofcase
elsenewvarcatchfinally
returnvoidcontinueforswitch
whiledefaultifthrowdelete
intryfunctionthiswith
debuggerfalsetruenull

  • 什么是保留字?
  • JavaScript预留的关键字,他们虽然现在没有作为关键字,但在以后的升级版本中有可能作为关键字
保留字
classenumextendssuperconstexport
importimplementsletprivatepublicyield
interfacepackageprotectedstatic

标识符

  • 什么是标识符?
  • 从字面上理解就是用来标识某些东西的符号,标识的目的就是为了将这些东西区分开来
  • 其实标识符的作用就跟人类的名字差不多,为了区分每个人,就在每个人出生的时候起了个名字
  • 日常生活中乔丹、刘德华、吴京这些都是标识符
  • 在编程中标识符就是程序员自己在程序中起的一些名字
  • 例如定义变量时的变量名称就是一个标识符var num;, 这里的num就是标识符

  • 标识符命名规则(必须遵守)
    • 只能由26个英文字母的大小写、10个阿拉伯数字0~9、下划线_、美元符号$组成
    • 不能以数字开头
    • 严格区分大小写,比如test和Test是2个不同的标识符
    • 不可以使用关键字、保留字作为标识符
    • JS底层保存标识符时实际上是采用的Unicode编码,所以理论上讲,所有的utf-8中含有的内容都可以作为标识符
不建议使用标识符
abstractdoublegotonativestaticboolean
enumimplementspackagesuperbyteexport
importprivatesynchronizecharextendsint
protectedthrowsclassfinalinterfacepublic
transientconstfloatlongshortvolatile
argumentsencodeURIInfinityNumberRegExpundefined
isFiniteObjectStringBooleanErrorRangeError
parseFloatSyntaxErrorDateevalJSONReferenceError
TypeErrordecodeURIEvalErrorMathURIErrordecodeURIComponent
FunctionNaNisNaNparseIntArrayencodeURICOmponent
  • 标识符命名规范(建议遵守)

    • 见名知意: 变量的名称要有意义(有利于提高阅读性)
    • 驼峰命名法: 首字母小写,第二个单词的首字母大写(有利于提高阅读性)
    • 例如: userName、myFirstName
  • 练习找出合法的标识符

fromNo12from#12my_Booleanmy-BooleanObj22ndObj
$lnjtest1json2DataMy_tExt_testtest!32
haha(da)tt哈哈_textjack_rosejack&roseGUI _123if

注释

  • 什么是注释?
  • 注释是在所有计算机语言中都非常重要的一个概念,从字面上看,就是注解、解释的意思
  • 注释可以用来解释某一段程序或者某一行代码是什么意思,方便程序员之间的交流。(假如我写完一行代码后,加上相应的注释,那么别人看到这个注释就知道我的这行代码是做什么用的)
  • 注释可以是任何文字,也就是说可以写中文
  • 在开发工具中注释一般是灰色或者绿色

江哥提示:

  • 初学者编写程序可以养成习惯:先写注释再写代码。
  • 将自己的思想通过注释先整理出来,在用代码去体现。
  • 因为代码仅仅是思想的一种体现形式而已。
  • 为什么要写注释?
  • 没写注释
      njQuery.extend({
          isString : function (str ) {
              return typeof str === 'string';
          },
          isHTML : function (str) {
              if (!njQuery.isString(str)){
                  return false;
              }if (str.charAt(0) == '<' && str.charAt(str.length - 1) == '>' && str.length >= 3) {
                  return true;
              }
              return false;
          },
          trim : function (str) {
              if( !njQuery.isString(str)){
                  return str;
              }else{
                  return str.trim ? str.trim() : str.replace(/^\\s+|\\s+$/g, '');
              }
          }
      });
    
  • 写了注释
      /*静态工具方法*/
      njQuery.extend({
          /**
           *  判断是否是字符串
           * @param 需要判断的内容
           * @returns 是返回true, 不是返回false
           */
          isString : function (str ) {
              return typeof str === 'string';
          },
          /**
           * 判断是不是html片段
           * @param 需要判断的内容
           * @returns 是返回true, 不是返回false
           */
          isHTML : function (str) {
              // 1.判断是否是字符串
              if (!njQuery.isString(str)){
                  return false;
              }
              // 2.如果字符串的第一个字母是<,最后一个字母是>,并且length >= 3,就可以认为是html片段。
              if (str.charAt(0) == '<' && str.charAt(str.length - 1) == '>' && str.length >= 3) {
                  return true;
              }
              // 3.其它情况一律返回false
              return false;
          },
          /**
           * 清除字符串首位空格
           * @param 需要清除的字符串
           * @returns 清除之后的新字符串
           */
          trim : function (str) {
              // 1.判断是否是字符串
              if( !njQuery.isString(str)){
                  return str;
              }else{
                  // 2.优先使用自带trim处理,
                  // 如果不支持再使用自己的方法处理
                  return str.trim ? str.trim() : str.replace(/^\\s+|\\s+$/g, '');
              }
          }
      });
    
  • 注释特点

    • 注释是写给人看的,不是给计算机看的。计算机怎么可能看得我们写的 中文。因此注释中的内容不会被解析器解析执行,但是会在源码中显示
    • 检查代码的作用
    • 排除错误
  • 注释使用

    • 单行注释

      // 我是被注释的内容
      var num;
      
      • 使用范围:任何地方都可以写注释:函数外面、里面,每一条语句后面
      • 作用范围: 从第二个斜线到这一行末尾
      • 快捷键:Ctrl+/
    • 多行注释

       /*我是被注释的内容*/
      var num;
      
      • 使用范围:任何地方都可以写注释:函数外面、里面,每一条语句后面
      • 作用范围: 从第一个/*到最近的一个*/
  • 注释使用注意

    • 单行注释可以嵌套单行注释、多行注释
        // 帅哥
        // 南哥 // 江哥
        // /* 大哥 */
      
    • 多行注释可以嵌套单行注释
      /*
        // 作者:LNJ
        // 描述:这个哥们F5一刷新
       */
      
    • 多行注释***不能***嵌套多行注释
        /* 
        哈哈哈
       /*嘻嘻嘻*/
         呵呵呵 
        */
      
  • 常用注释

                          _ooOoo_
                         o8888888o
                         88" . "88
                         (| -_- |)
                          O\\ = /O
                      ____/`---'\\____
                    .   ' \\\\| |// `.
                     / \\\\||| : |||// \\
                   / _||||| -:- |||||- \\
                     | | \\\\\\ - /// | |
                   | \\_| ''\\---/'' | |
                    \\ .-\\__ `-` ___/-. /
                 ___`. .' /--.--\\ `. . __
              ."" '< `.___\\_<|>_/___.' >'"".
             | | : `- \\`.;`\\ _ /`;.`/ - ` : | |
               \\ \\ `-. \\_ __\\ /__ _/ .-` / /
       ======`-.____`-.___\\_____/___.-`____.-'======
                          `=---='

       .............................................
              佛祖保佑                   有无BUG

什么是数据?

  • 生活中无时无刻都在跟数据打交道
  • 例如:人的体重、身高、收入、性别等数据等
  • 在我们使用计算机的过程中,也会接触到各种各样的数据
  • 例如: 文档数据、图片数据、视频数据等

数据分类

  • 静态的数据

    • 静态数据是指一些永久性的数据,一般存储在硬盘中。硬盘的存储空间一般都比较大,现在普通计算机的硬盘都有500G左右,因此硬盘中可以存放一些比较大的文件
    • 存储的时长:计算机关闭之后再开启,这些数据依旧还在,只要你不主动删掉或者硬盘没坏,这些数据永远都在
    • 哪些是静态数据:静态数据一般是以文件的形式存储在硬盘上,比如文档、照片、视频等。
  • 动态的数据

    • 动态数据指在程序运行过程中,动态产生的临时数据,一般存储在内存中。内存的存储空间一般都比较小,现在普通计算机的内存只有8G左右,因此要谨慎使用内存,不要占用太多的内存空间
    • 存储的时长:计算机关闭之后,这些临时数据就会被清除
    • 哪些是动态数据:当运行某个程序(软件)时,整个程序就会被加载到内存中,在程序运行过程中,会产生各种各样的临时数据,这些临时数据都是存储在内存中的。当程序停止运行或者计算机被强制关闭时,这个程序产生的所有临时数据都会被清除。
  • 既然硬盘的存储空间这么大,为何不把所有的应用程序加载到硬盘中去执行呢?

    • 主要原因就是内存的访问速度比硬盘快N倍

  • 静态数据和动态数据的相互转换
    • 也就是从磁盘加载到内存
  • 动态数据和静态数据的相互转换
  • 也就是从内存保存到磁盘
  • 数据的计量单位
    • 不管是静态还是动态数据,都是0和1组成的
    • 数据越大,包含的0和1就越多
1 B(Byte字节) = 8 bit()
// 00000000 就是一个字节
// 111111111 也是一个字节
// 10101010 也是一个字节
// 任意8个0和1的组合都是一个字节
1 KB(KByte) = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB

JavaScript数据类型概述

  • 作为程序员最关心的是内存中的动态数据, 因为我们写的程序就是在内存中的

  • 程序在运行过程中会产生各种各样的临时数据, 为了方便数据的运算和操作, JavaScript对这些数据进行了分类, 提供了丰富的数据类型

  • 在JS中一共有六种数据类型

    • Number 数值(基本数据类型)
    • String 字符串(基本数据类型)
    • Boolean 布尔(基本数据类型)
    • Undefined 未定义(基本数据类型)
    • Null 空值***(基本数据类型)***
    • Object 对象(引用数据类型)
  • 如何查看数据类型?

    • 使用typeof操作符可以用来检查数据类型。
    • 使用格式:typeof 数据,例如 typeof 123; typeof num;
    console.log(typeof 123); // number
    var num = 10;
    console.log(typeof num); // number
    
    • typeof操作符会将检查的结果以字符串的形式返回给我们
    var value= 10;
    // 此时将value的数据类型number以字符串返回给我们, 存入到res变量中
    var res = typeof value; 
    // 此时检查res的数据类型为string, 证明typeof返回给我们的是一个字符串
    console.log(typeof res); // string
    

字符串类型

  • String用于表示一个字符序列,即字符串
  • 字符串需要使用 ’或“ 括起来
var str1 = "hello";
var str2 = `nj`;
var str5 = `hello nj"; // 错误
console.log(typeof str1 ); // string
console.log(typeof str2); // string
  • 相同引号不能嵌套,不同引号可以嵌套
  • 双引号不能放双引号,单引号不能放单引号
var str3 = "hello "nj""; // 错误
var str4 = `hello `nj``; // 错误
var str5 = "hello 'nj'"; // 正确
var str6 = `hello "nj"`;// 正确
  • 给变量加上引号, 那么变量将变为一个常量
var num = 110;
console.log(num); // 输出变量中的值
console.log("num"); // 输出常量num

Number类型

  • 在JS中所有的数值都是Number类型(整数和小数)
var num1= 123;
var num2= 3.14;
console.log(typeof num1); // number
console.log(typeof num2); // number
  • 由于内存的限制,ECMAScript 并不能保存世界上所有的数值
  • 最大值:Number.MAX_VALUE
    console.log(Number.MAX_VALUE);  // 1.7976931348623157e+308
    
  • 最小值:Number.MIN_VALUE
    console.log(Number.MIN_VALUE);  // 5e-324
    
  • 无穷大:Infinity, 如果超过了最大值就会返回该值
    console.log(Number.MAX_VALUE + Number.MAX_VALUE); // Infinity
    
  • 无穷小:-Infinity, 如果超过了最小值就会返回该值
     console.log(typeof Infinity); // number
     console.log(typeof -Infinity); // number
    
  • NaN 非法数字(Not A Number),JS中当对数值进行计算时没有结果返回,则返回NaN
    var num3 = NaN;
    console.log(typeof num3); // number
    
  • Number类型注意点
    • JS中整数的运算可以保证精确的结果
    var sum1 = 10 + 20;
    console.log(sum1); // 30
    
    • 在JS中浮点数的运算可能得到一个不精确的结果
    var sum1 = 10.1 + 21.1;
    console.log(sum1); // 31.200000000000003
    

Boolean 布尔值

  • 布尔型也被称为逻辑值类型或者真假值类型
  • 布尔型只能够取真(true)和假(false)两种数值
var bool1 = true;
var bool2 = false;
console.log(typeof bool1); // boolean
console.log(typeof bool2); // boolean
  • 虽然Boolean 类型的字面值只有两个,但 ECMAScript 中所有类型的值都有与这两个 Boolean 值等价的值
    • 任何非零数值都是true, 包括正负无穷大, 只有0和NaN是false
    • 任何非空字符串都是true, 只有空字符串是false
    • 任何对象都是true, 只有null和undefined是false
var bool3 = Boolean(0);
console.log(bool3); // false
var bool4 = Boolean(1);
console.log(bool4); // true
var bool5 = Boolean(-1);
console.log(bool4); // true
var bool6 = Boolean(Infinity);
console.log(bool4); // true
var bool7 = Boolean(-Infinity);
console.log(bool4); // true
var bool8 = Boolean(NaN);
console.log(bool8); // false
var bool9 = Boolean(undefined);
console.log(bool8); // false
var bool10 = Boolean(null);
console.log(bool8); // false
var bool11 = Boolean("");
console.log(bool8); // false
var bool12 = Boolean("abc");
console.log(bool12); // true

Null和Undefined

  • Undefined这是一种比较特殊的类型,表示变量未赋值,这种类型只有一种值就是undefined
var num;
console.log(num);  //结果是undefined
  • undefined是Undefined类型的字面量
    • 前者undefined和10, "abc"一样是一个常量
    • 后者Undefined和Number,Boolean一样是一个数据类型
    • 需要注意的是typeof对没有初始化和没有声明的变量都会返回undefined。
var value1 = undefined;
console.log(typeof value); //结果是undefined

var value2;
console.log(typeof  value2); //结果是undefined
  • Null 类型是第二个只有一个值的数据类型,这个特殊的值是 null
  • 从语义上看null表示的是一个空的对象。所以使用typeof检查null会返回一个Object
var test1= null;
console.log(typeof test1);
  • undefined值实际上是由null值衍生出来的,所以如果比较undefined和null是否相等,会返回true
var test1 = null;
var test2 = undefined;
console.log(test1 == test2);
console.log(test1 === test2);

什么是数据类型转换

  • 将一个数据类型转换为其他的数据类型
    • 例如: 将Number类型转换为Boolean类型
    • 例如: 将Number类型转换为字符串类型
    • … …

将其它类型转换为字符串

调用被转换数据类型的toString()方法

  var num1 = 10;
  var res1 = num1.toString(); // 重点
  console.log(res1); // 10
  console.log(typeof res1); // string

  var num2 = true;
  var res2 = num2.toString(); // 重点
  console.log(res2); // true
  console.log(typeof res2); // string
  • null和undefined这两个值没有toString()方法,如果调用他们的方法,会报错
  var num3 = undefined;
  var res3 = num3.toString(); // 报错
  console.log(res3);

  var num4 = null;
  var res4 = num4.toString(); // 报错
  console.log(res4);

  var num5 = NaN;
  var res5 = num5.toString();
  console.log(res5); // NaN
  console.log(typeof res5); // String
  • 该方法不会影响到原变量,它会将转换的结果返回
 var num6 = 10;
 var res6 = num6.toString();
 console.log(typeof num6); // number
 console.log(typeof res6); // string
  • 数值类型的toString(),可以携带一个参数,输出对应进制的值(暂时不用了解, 讲到进制转换再回来看)
 var 

以上是关于肝了4.5万字,手把手带你玩转JavaScript(建议收藏)的主要内容,如果未能解决你的问题,请参考以下文章

手把手带你玩转Spark机器学习-使用Spark进行文本处理

手把手带你玩转Spark机器学习-使用Spark构建分类模型

2 万字长文| 手摸手带你玩转 JQuery,后端程序员都能上手系列第一期 (建议收藏)

2 万字长文| 手摸手带你玩转 JQuery,后端程序员都能上手系列第一期 (建议收藏)

手把手带你玩转Linux

一篇文章带你玩转Mac Finder