8

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。

该文为前端培训-初级阶段(13、18)的补充内容 (介绍了 ECMAScript 历史,ES6 常用点)。

本文介绍ECMAScript基础知识

  1. 前端培训-初级阶段(13) - ECMAScript (语法、变量、值、类型、运算符、语句)
    上节的基础内容知识,这节我们会用到。默认已读。

clipboard.png

我们要讲什么

  1. ECMAScript 基础对象(Object、Boolean、Number、String)
  2. 常用内置对象(Date、Array、Math、RegExp、global、Function、Event、arguments、JSON)
  3. ECMAScript 函数(声明、调用、返回值、闭包、递归)

ECMAScript 基础对象

在 ECMAScript 中,所有对象并非同等创建的。
一般来说,可以创建并使用的对象有三种:本地对象、内置对象和宿主对象。

ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。简单来说,本地对象就是 ECMA-262 定义的类(引用类型)。它们包括:Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError
ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。
所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。所有 BOM 和 DOM 对象都是宿主对象。

Object 对象

Object 是所有对象的基础。JavaScript 中的所有对象都来自 Object ;所有对象从 Object.prototype 继承方法和属性,尽管它们可能被覆盖。例如,其他构造函数的原型将覆盖 constructor 属性并提供自己的 toString() 方法。Object 原型对象的更改将传播到所有对象,除非受到这些更改的属性和方法将沿原型链进一步覆盖。
类型 key 用法 作用
属性 length Object.length Object.length 值为1
属性 prototype Object.prototype 可以为所有 Object 类型的对象添加属性
方法 assign Object.assign() 通过复制一个或多个对象来创建一个新的对象
方法 create Object.create() 使用指定的原型对象和属性创建一个新对象
方法 defineProperty Object.defineProperty() 给对象添加一个属性并指定该属性的配置
方法 defineProperties Object.defineProperties() 给对象添加多个属性并分别指定它们的配置
方法 entries Object.entries() 返回给定对象自身可枚举属性的[key, value]数组
方法 freeze Object.freeze() 冻结对象:其他代码不能删除或更改任何属性
方法 getOwnPropertyDescriptor Object.getOwnPropertyDescriptor() 返回对象指定的属性配置
方法 getOwnPropertyNames Object.getOwnPropertyNames() 返回一个数组,它包含了指定对象所有的可枚举或不可枚举的属性名
方法 getOwnPropertySymbols Object.getOwnPropertySymbols() 返回一个数组,它包含了指定对象自身所有的符号属性
方法 getPrototypeOf Object.getPrototypeOf() 返回指定对象的原型对象
方法 is Object.is() 比较两个值是否相同。所有 NaN 值都相等(这与==和===不同)
方法 isExtensible Object.isExtensible() 判断对象是否可扩展
方法 isFrozen Object.isFrozen() 判断对象是否已经冻结
方法 isSealed Object.isSealed() 判断对象是否已经密封
方法 keys Object.keys() 返回一个包含所有给定对象自身可枚举属性名称的数组
方法 preventExtensions Object.preventExtensions() 防止对象的任何扩展
方法 seal Object.seal() 防止其他代码删除对象的属性
方法 setPrototypeOf Object.setPrototypeOf() 设置对象的原型(即内部[[Prototype]]属性)
方法 values Object.values() 返回给定对象自身可枚举值的数组
原型属性 ([]).constructor === Array Object.prototype.constructor 特定的函数,用于创建一个对象的原型
原型属性 ([]).__proto__ === Array.prototype Object.prototype.__proto__ 指向当对象被实例化的时候,用作原型的对象
原型方法 Object.prototype.hasOwnProperty() 返回一个布尔值 ,表示某个对象是否含有指定的属性,而且此属性非原型链继承的
原型方法 Object.prototype.isPrototypeOf() 返回一个布尔值,表示指定的对象是否在本对象的原型链中
原型方法 Object.prototype.propertyIsEnumerable() 判断指定属性是否可枚举
原型方法 Object.prototype.toLocaleString() 直接调用 toString()方法
原型方法 Object.prototype.toString() 返回对象的字符串表示
原型方法 Object.prototype.valueOf() 返回指定对象的原始值

Boolean 对象

这个对象非常的简单。只有从Object哪里基础来的方法和属性。当做函数调用,就是把值转换成布尔类型

如果第一个参数不是布尔值,则会将其转换为布尔值。如果省略该参数,或者其值为 0、-0、null、false、NaN、undefined、或者空字符串(""),则生成的 Boolean 对象的值为 false。如果传入的参数是 DOM 对象 document.all,也会生成值为 false 的 Boolean 对象。任何其他的值,包括值为 "false" 的字符串和任何对象,都会创建一个值为 true 的 Boolean 对象。
注意不要将基本类型中的布尔值 true 和 false 与值为 true 和 false 的 Boolean 对象弄混了。
当 Boolean 对象用于条件语句的时候(译注:意为直接应用于条件语句),任何不是 undefined 和 null 的对象,包括值为 false 的 Boolean 对象,都会被当做 true 来对待。例如,下面 if 语句中的条件为真:
var x = new Boolean(false);
if (x) {
  console.log(typeof x, typeof true, typeof false)
}

Number 对象

类型 key 用法 作用
属性 EPSILON Number.EPSILON 两个可表示(representable)数之间的最小间隔
属性 MAX_SAFE_INTEGER Number.MAX_SAFE_INTEGER JavaScript 中最大的安全整数 (253 - 1)
属性 MAX_VALUE Number.MAX_VALUE 能表示的最大正数。最小的负数是 -MAX_VALUE
属性 MIN_SAFE_INTEGER Number.MIN_SAFE_INTEGER JavaScript 中最小的安全整数 (-(253 - 1))
属性 MIN_VALUE Number.MIN_VALUE 能表示的最小正数即最接近 0 的正数 (实际上不会变成 0)。最大的负数是 -MIN_VALUE
属性 NaN Number.NaN 特殊的“非数字”值
属性 NEGATIVE_INFINITY Number.NEGATIVE_INFINITY 特殊的负无穷大值,在溢出时返回该值
属性 POSITIVE_INFINITY Number.POSITIVE_INFINITY 特殊的正无穷大值,在溢出时返回改值
属性 prototype Number.prototype Number 对象上允许的额外属性
方法 isNaN Number.isNaN() 确定传递的值是否是 NaN
方法 isFinite Number.isFinite() 确定传递的值类型及本身是否是有限数
方法 isInteger Number.isInteger() 确定传递的值类型是“number”,且是整数
方法 isSafeInteger Number.isSafeInteger() 确定传递的值是否为安全整数 ( -(253 - 1) 至 253 - 1之间)
方法 toInteger Number.toInteger() 计算传递的值并将其转换为整数 (或无穷大)
方法 parseFloat Number.parseFloat() 和全局对象 parseFloat() 一样
方法 parseInt Number.parseInt() 和全局对象 parseInt() 一样
原型方法 toExponential Number.prototype.toExponential() 返回以科学计数法表示的数字字符串
原型方法 toFixed Number.prototype.toFixed() 返回固定小数位的数字字符串(四拾伍入)
原型方法 toLocaleString Number.prototype.toLocaleString() 返回以本地语言为主的数字字符串。会覆盖 Object.prototype.toLocaleString()。
原型方法 toPrecision Number.prototype.toPrecision() 返回固定位数表示的数字字符串(小数点不记位,四拾伍入、位数不够会返回科学计数法)
原型方法 toString Number.prototype.toString() 返回以指定基数表示的数字字符串。会覆盖 Object.prototype.toString()
原型方法 valueOf Number.prototype.valueOf() 返回以原始数值。会覆盖 Object.prototype.valueOf()

String 对象

类型 key 用法 作用
属性 length ''.length 返回文字长度
方法 String.fromCharCode() String.fromCharCode(97) == 'A' 通过 一系列UTF-16代码单元的数字。 范围介于0到65535(0xFFFF)之间。 大于0xFFFF的数字将被截断。 不进行有效性检查。 创建字符串
方法 String.fromCodePoint() String.fromCodePoint(65,97) == 'Aa' 通过Unicode创建字符串
原型方法 charAt() '李li'.charAt(1) == 'l' 返回特定位置的字符
原型方法 charCodeAt() '李li'.charCodeAt(0) == 26446 返回表示给定索引的字符的Unicode的值
原型方法 codePointAt() '李li'.codePointAt(0) == 26446 返回表示给定索引的字符的Unicode的值
原型方法 concat() 'l'.concat('i') == 'li' 连接两个字符串文本,并返回一个新的字符串
原型方法 includes() 'li'.includes('i') 判断一个字符串里是否包含其他字符串
原型方法 endsWith() 'li'.endsWith('i') 判断一个字符串的结尾是否包含其他字符串中的字符
原型方法 indexOf() 'li'.indexOf('i') 从字符串对象中返回首个被发现的给定值的索引值,如果没有找到则返回-1
原型方法 lastIndexOf() 'li'.lastIndexOf('i') 从字符串对象中返回最后一个被发现的给定值的索引值,如果没有找到则返回-1
原型方法 localeCompare() 返回一个数字表示是否引用字符串在排序中位于比较字符串的前面,后面,或者二者相同
原型方法 match() 'onmousemove'.match(/on(w+)/) 使用正则表达式与字符串相比较
原型方法 normalize() 返回调用字符串值的Unicode标准化形式
原型方法 padEnd() '1'.padEnd(5, ' ') 在当前字符串尾部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串
原型方法 padStart() '1'.padStart(5, '0') 在当前字符串头部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串
原型方法 repeat() '*'.repeat(10) 返回指定重复次数的由元素组成的字符串对象
原型方法 replace() '李?'.replace('?','**') 被用来在正则表达式和字符串直接比较,然后用新的子串来替换被匹配的子串
原型方法 search() '李?'.search('?') 对正则表达式和指定字符串进行匹配搜索,返回第一个出现的匹配项的下标
原型方法 slice() "李**".slice(0,2) 摘取一个字符串区域,返回一个新的字符串
原型方法 split() 'a,b,123,f'.split(',') 通过分离字符串成字串,将字符串对象分割成字符串数组
原型方法 startsWith() 判断字符串的起始位置是否匹配其他字符串中的字符
原型方法 substr() 通过指定字符数返回在指定位置开始的字符串中的字符
原型方法 substring() 返回在字符串中指定两个下标之间的字符
原型方法 toLocaleLowerCase() 根据当前区域设置,将符串中的字符转换成小写。对于大多数语言来说,toLowerCase的返回值是一致的
原型方法 toLocaleUpperCase() 根据当前区域设置,将字符串中的字符转换成大写,对于大多数语言来说,toUpperCase的返回值是一致的
原型方法 toLowerCase() 将字符串转换成小写并返回
原型方法 toSource() 返回一个对象文字代表着特定的对象。你可以使用这个返回值来创建新的对象。重写 Object.prototype.toSource 方法
原型方法 toString() 返回用字符串表示的特定对象。重写 Object.prototype.toString 方法
原型方法 toUpperCase() 将字符串转换成大写并返回
原型方法 trim() ' 1 '.trim() 从字符串的开始和结尾去除空格。参照部分 ECMAScript 5 标准
原型方法 trimStart()trimLeft() ' 1 '.trimStart() 从字符串的左侧去除空格
原型方法 trimEnd()trimRight() ' 1 '.trimEnd() 从字符串的右侧去除空格
原型方法 valueOf() 返回特定对象的原始值。重写 Object.prototype.valueOf 方法

常用内置对象

这个我就直接说常用的了。

Date

Date 对象是自1970年1月1日(UTC)起经过的毫秒数。

  1. 实例化方式

    new Date();//当前时间
    new Date(Number);//传入的毫秒数转换成时间
    new Date(dateString);//传入的时间格式转换为时间。这里有一些坑(低版本IE、ios、chrome)实现的规范不一样,导致有的格式解析不出来,可以用[momentjs][3]。
    new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
    注意:只能将 Date 作为构造函数调用,才能实例化(instantiate) Date 对象:若将它作为常规函数调用(即不加 new 操作符),则将会返回一个字符串,而非 Date 对象。另外,不像其他的 JavaScript 对象类型,Date 对象没有字面量语法(literal syntax)。
  2. 方法

    1. Date.now() 返回自 1970-1-1 00:00:00 UTC(世界标准时间)至今所经过的毫秒数。
      等效写法+new Date(),new Date().getTime()
    2. Date.parse() 解析一个表示日期的字符串,并返回从 1970-1-1 00:00:00 所经过的毫秒数。
    3. Date.UTC() 接受和构造函数最长形式的参数相同的参数(从2到7),并返回从 1970-01-01 00:00:00 UTC 开始所经过的毫秒数。
  3. 原型方法

    1. getDay()周,getFullYear()年,getMonth()月,getDate()日,getHours()时,getMinutes()分,getSeconds()
    2. getTimezoneOffset() 返回当前时区的时区偏移。
    3. set方法同上,需要注意的地方有setHours()可以把时分秒毫秒都设置了

Array

  1. Array数组对象的forEach、map、filter、reduce
  2. join 合并成串
  3. concat 合并其他数组
  4. slice 分割数组

Math

  1. Math.random() 随机数。来个公式(end-start+1)*num+start
    比如 60-90区间内(90-60+1)*Math.random()+60>>0即可得到区间内整数
  2. Math.ceil 向上取整Math.ceil(5.1)
  3. Math.floor 向下取整Math.floor(1.9)
  4. Math.round 四拾伍入Math.round(2.3)
  5. Math.pow Math.pow(3,5)等同于3**5,但是前者兼容更好

RegExp

原生的方法其实很少用。需要注意的地方是,有部分函数会记录上次差到的点。一般都是用字符串的 replacematch

JSON

低版本 IE 没有。需要使用 eval
提供了 JSON.stringifyJSON.parse()用来序列化与反序列化

//提供一个tips,你可以在控制台试试哟。
JSON.stringify([{
    userid: 7848950,
    nickname: 'abc'
},{
    userid: 920110633,
    nickname: 'abc'
},{
    userid: 7848952,
    nickname: 'abc'
}], null, '   ')

ECMAScript 函数(声明、调用、返回值、闭包、递归)

函数声明

  1. 函数声明 function fun(){}
  2. 函数表达式 fun = function fun(){}
  3. IFFE void function(){console.log(1)}()
  4. 构造函数 new Function('a','b','return a+b')(1,2)

函数调用

function fun(){console.log(1)};fun() 通过括号来调用

返回值

function fun(){return 1};console.log(fun()) 函数内部通过return来返回

闭包

  1. 什么是作用域
    作用域(scope)指的是变量存在的范围。 在 es5 中的,Javascript 只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。(es6中又新增了块级作用域)全局作用域可以在代码的任何地方都能被访问。
  2. 什么是作用域链
    是指作用域生成的路径。当代码在一个执行环境中执行时,就会创建一个作用域链。我们有可能两个 function 内都使用了 state 这个变量,我们不希望他共享,他被限制在了自己的作用域中。
    内部环境可以通过作用域链访问所有外部环境,但是外部环境不能访问内部环境中的任何变量和函数。
    在 js 中与作用域链相似的有原型链
  3. 那么什么是闭包呢?
    闭包就是依赖这个特性,思考如下代码。可以让我们的代码和外部环境隔离。

    var getNum = (function(){
      var sum = 0;//闭包中的变量
      return function(){
          return ++sum//内部可以访问
      }
    })()
    getNum();//1,这里可以获取调用次数
    sum = 1000;//这里改变的其实是全局的,因为他拿不到闭包内的sum
    getNum();//2,这里可以获取调用次数

回调函数

有的教程里面叫高阶函数,思考如下代码

[1,2,3].map(v=>v*2);//map就是一个高阶函数,通过把回调传递进去。对原数组进行操作。

递归函数

这个主要是用来没有预期的情况。比如遍历一颗树。你不知道要循环多少次。或者说当前有个dom节点,你需要找到他的一个父级.editor_main

//求菲波那切数列
function factorial(num){
   if(num <= 1){
       return 1
   }else {
       return num * factorial(num - 1);
   }
}

后记

主讲人的讲稿地址
这里也要吐槽一下自己,断更这么久,实在是太忙了。

参考文献

  1. JavaScript 标准库

linong
29.2k 声望9.5k 粉丝

Read-Search-Ask