JavaScript学习笔记(一)

作者:cedar(https://www.jianshu.com/writer#/notebooks/28559629/notes/32531540)

一、基础知识

  1. JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到中。
    包含的代码就是JavaScript代码,它将直接被浏览器执行。
  2. 第二种方法是把JavaScript代码放到一个单独的.js文件,然后在HTML中通过引入这个文件
    把JavaScript代码放入一个单独的.js文件中更利于维护代码,并且多个页面可以各自引用同一份.js文件。
    可以在同一个页面中引入多个.js文件,还可以在页面中多次编写,浏览器按照顺序依次执行。
  3. 编写JavaScript:Visual Studio Code,Sublime Text,Notepad++。
  4. 运行JavaScript:要让浏览器运行JavaScript,必须先有一个HTML页面,在HTML页面中引入JavaScript,然后,让浏览器加载该HTML页面,就可以执行JavaScript代码。
  5. 调试JavaScript:需要安装Google Chrome浏览器,Chrome浏览器对开发者非常友好,可以让你方便地调试JavaScript代码。打开浏览器中开发者工具,点击控制台(Console),可以在这个面板里直接输入Javascript代码,按回车执行。

1、基本语法

  1. JavaScript的语法和Java语言类似,每个语句以;结束,语句块用{...}。但是,JavaScript并不强制要求在每个语句的结尾加;,浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上;。
  2. 注意花括号{...}内的语句具有缩进,通常是4个空格。缩进不是JavaScript语法要求必须的,但缩进有助于我们理解代码的层次,所以编写代码时要遵守缩进规则。
  3. JavaScript本身对嵌套的层级没有限制,但是过多的嵌套无疑会大大增加看懂代码的难度。遇到这种情况,需要把部分代码抽出来,作为函数来调用,这样可以减少代码的复杂度。
  4. 注释:以//开头直到行末的字符被视为行注释;另一种块注释是用/*...*/把多行字符包裹起来,把一大“块”视为一个注释
  5. 大小写:JavaScript严格区分大小写,如果弄错了大小写,程序将报错或者运行不正常。

2、数据类型和变量

  1. Number:JavaScript不区分整数和浮点数,统一用Number表示。
  2. 字符串:字符串是以单引号'或双引号"括起来的任意文本。
  3. 布尔值:布尔值和布尔代数的表示完全一致。
  4. 比较运算符:JavaScript允许对任意数据类型作比较。
    • ==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;
    • ===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。
    • NaN这个特殊的Number与所有其他值都不相等,包括它自己。
  5. null和undefined:null表示一个"空"的值。undefined表示值未定义。
  6. 数组:数组是一组按顺序排列的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型。另一种创建数组的方法是通过Array()函数实现。
  7. 对象:JavaScript的对象是一组由键-值组成的无序集合。JavaScript对象的键都是字符串类型,值可以是任意数据类型。
  8. 变量:变量在JavaScript中就是用一个变量名表示,变量名是大小写英文、数字、$和_的组合,且不能用数字开头。变量名也不能是JavaScript的关键字,如if、while等。申明一个变量用var语句。要显示变量的内容,可以用console.log(x),打开Chrome的控制台就可以看到结果。
  9. strict模式:使用var申明的变量则不是全局变量,它的范围被限制在该变量被申明的函数体内,同名变量在不同的函数体内互不冲突。ECMA在后续规范中推出了strict模式,在strict模式下运行的JavaScript代码,强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误。启用strict模式的方法是在JavaScript代码的第一行写上:'use strict';

3、字符串

  1. 如果字符串内部既包含'又包含"怎么办?可以用转义字符\来标识。
  2. 多行字符串:最新的ES6标准新增了一种多行字符串的表示方法,用反引号`...` 表示。
  3. 模板字符串:ES6新增了一种模板字符串,表示方法和上面的多行字符串一样,但是它会自动替换字符串中的变量。
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;
alert(message);
  1. 操作字符串:要获取字符串某个指定位置的字符,使用类似Array的下标操作,索引号从0开始。需要特别注意的是,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果。
    • toUpperCase()把一个字符串全部变为大写
    • toLowerCase()把一个字符串全部变为小写
    • indexOf()会搜索指定字符串出现的位置
    • substring()返回指定索引区间的子串

4、数组

  1. JavaScript的Array可以包含任意数据类型,并通过索引来访问每个元素。
  2. 直接给Arraylength赋一个新的值会导致Array大小的变化。
  3. 如果通过索引赋值时,索引超过了范围,同样会引起Array大小的变化。
  4. indexOf:与String类似,Array也可以通过indexOf()来搜索一个指定的元素的位置。
  5. slice:slice()就是对应String的substring()版本,它截取Array的部分元素,然后返回一个新的Array
  6. push和pop:push()Array的末尾添加若干元素,pop()则把Array的最后一个元素删除掉。
  7. unshift和shift:如果要往Array的头部添加若干元素,使用unshift()方法,shift()方法则把Array的第一个元素删掉。
  8. sort:sort()可以对当前Array进行排序,它会直接修改当前Array的元素位置,直接调用时,按照默认顺序排序。
  9. reverse:反转。
  10. splice:splice()方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素。
  11. concat:数组连接起来。concat()方法并没有修改当前Array,而是返回了一个新的Array
  12. join:join()把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串。
  13. 多维数组:如果数组的某个元素又是一个Array,则可以形成多维数组。

5、对象

  1. JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。
  2. JavaScript规定,访问不存在的属性不报错,而是返回undefined
  3. 由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性。
  4. 如果我们要检测xiaoming是否拥有某一属性,可以用in操作符。不过要小心,如果in判断一个属性存在,这个属性不一定是xiaoming的,它可能是xiaoming继承得到的。

6、条件判断

  1. JavaScript使用if () { ... } else { ... }来进行条件判断。
  2. 多行条件判断:如果还要更细致地判断条件,可以使用多个if...else...的组合。

7、循环

  1. JavaScript的循环有两种,一种是for循环,通过初始条件、结束条件和递增条件来循环执行语句块。
  2. while循环只有一个判断条件,条件满足,就不断循环,条件不满足时则退出循环。

8、Map和Set

  1. JavaScript的默认对象表示方式{}可以视为其他语言中的MapDictionary的数据结构,即一组键值对。但是JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。最新的ES6规范引入了新的数据类型Map。
  2. Map:Map是一组键值对的结构,具有极快的查找速度。
  3. Set:SetMap类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key

9、iterable

  1. 遍历Array可以采用下标循环,遍历MapSet就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,ArrayMapSet都属于iterable类型。
  2. 具有iterable类型的集合可以通过新的for ... of循环来遍历。
  3. for ... in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。
  4. 更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数。

二、函数

1、函数的定义和调用

1.定义函数:

  function abs(x) 
  {
    if (x >= 0) 
    {
      return x;
    } 
    else
    {
      return -x;
    }
  }
  1. 调用函数:JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数。传入的参数比定义的少也没有问题,要避免收到undefined,可以对参数进行检查。
  2. arguments:JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。利用arguments,你可以获得调用者传入的所有参数。实际上arguments最常用于判断传入参数的个数。
  3. rest参数:
function foo(a, b) {
  var i, rest = [];
  if (arguments.length > 2) {
   for (i = 2; i

如果数组本身还有嵌套,也可以通过下面的形式进行解构赋值,注意嵌套层次和位置要保持一致。

let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
x; // 'hello'
y; // 'JavaScript'
z; // 'ES6'

3、方法

  1. 在一个对象中绑定函数,称为这个对象的方法。在一个方法内部,this是一个特殊变量,它始终指向当前对象,也就是xiaoming这个变量。所以,this.birth可以拿到xiaomingbirth属性。

  2. ECMA决定,在strict模式下让函数的this指向undefined,因此,在strict模式下,你会得到一个错误。

  3. apply:要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。另一个与apply()类似的方法是call(),唯一区别是:

    • apply()把参数打包成Array再传入;
    • call()把参数按顺序传入。

    对普通函数调用,我们通常把this绑定为null。

  4. 装饰器:JavaScript的所有对象都是动态的,即使内置的函数,我们也可以重新指向新的函数。

4、高阶函数

  1. JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
  2. map/reduce:由于map()方法定义在JavaScript的Array中,我们调用Arraymap()方法,传入我们自己的函数,就得到了一个新的Array作为结果。
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']

Arrayreduce()把一个函数作用在这个Array[x1, x2, x3...]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算。

  1. filter:filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。和map()类似,Arrayfilter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。filter()接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身。
  2. sort:Arraysort()方法默认把所有元素先转换为String再排序,结果'10'排在了'2'的前面,因为字符'1'比字符'2'的ASCII码小。sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。

5、闭包

  1. 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
  2. 在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
  3. 注意到返回的函数在其定义内部引用了局部变量arr,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
  4. 在返回的对象中,实现了一个闭包,该闭包携带了局部变量x,并且,从外部代码根本无法访问到变量x。换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。

6、箭头函数

var fn = x => x * x;
  1. 箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }return
  2. 如果参数不是一个,就需要用括号()括起来。
  3. 箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。

7、generator

  1. generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。

  2. generator和函数不同的是,generator由function*定义(注意多出的*号),并且,除了return语句,还可以用yield返回多次。

    function* fib(max) {
     var
         t,
         a = 0,
         b = 1,
         n = 0;
     while (n < max) {
         yield a;
         [a, b] = [b, a + b];
         n ++;
     }
     return;
    }
    
  3. 直接调用一个generator和调用函数不一样,fib(5)仅仅是创建了一个generator对象,还没有去执行它。

  4. 调用generator对象有两个方法,一是不断地调用generator对象的next()方法。next()方法会执行generator的代码,然后,每次遇到yield x;就返回一个对象{value: x, done: true/false},然后“暂停”。返回的value就是yield的返回值,done表示这个generator是否已经执行结束了。

  5. 第二个方法是直接用for ... of循环迭代generator对象,这种方式不需要我们自己判断done

三、标准对象

  1. 为了区分对象的类型,我们用typeof操作符获取对象的类型,它总是返回一个字符串。
  2. 特别注意null的类型是objectArray的类型也是object,如果我们用typeof将无法区分出nullArray和通常意义上的object——{}
  3. 包装对象:numberbooleanstring都有包装对象。没错,在JavaScript中,字符串也区分string类型和它的包装类型。包装对象用new创建。
  4. 虽然包装对象看上去和原来的值一模一样,显示出来也是一模一样,但他们的类型已经变为object了。
  5. typeof操作符可以判断出numberbooleanstringfunctionundefined;判断Array要使用Array.isArray(arr);判断null请使用myVar === null
  6. 判断某个全局变量是否存在用typeof window.myVar === 'undefined';函数内部判断某个变量是否存在用typeof myVar === 'undefined'

1、Date

  1. 在JavaScript中,Date对象用来表示日期和时间。

2、RegExp

  1. 正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
  2. 要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符。
  3. 如果要匹配'010-12345'这样的号码呢?由于'-'是特殊字符,在正则表达式中,要用'\'转义,所以,上面的正则是\d{3}\-\d{3,8}。、
  4. RegExp对象的test()方法用于测试给定的字符串是否符合条件。
  5. 分组:除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。如果正则表达式中定义了组,就可以在RegExp对象上用exec()方法提取出子串来。
  6. 贪婪匹配:正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。
  7. 全局搜索:JavaScript的正则表达式还有几个特殊的标志,最常用的是g,表示全局匹配。全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后,每次运行exec(),正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引。

3、JSON

  1. JSON是JavaScript Object Notation的缩写,它是一种数据交换格式。
  2. JSON还定死了字符集必须是UTF-8,表示多语言就没有问题了。为了统一解析,JSON的字符串规定必须用双引号"",Object的键也必须用双引号""
  3. 反序列化:拿到一个JSON格式的字符串,我们直接用JSON.parse()把它变成一个JavaScript对象。

学习参考:https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000

你可能感兴趣的:(JavaScript学习笔记(一))