1. 字符串、数组以及对象的操作方法
1.1 字符串方法
str.charAt(index)
:获取字符串特定位置的字符;str.charCodeAt(index)
:获取字符串特定位置字符的unicode编码;String.fromCharCode(num1, num2, ...)
:获取unicode编码对应的字符;str.indexOf(searchValue)
:查找str中是否有对应的字符串并返回其第一次出现时对应的索引值;str.lastIndexOf(searchValue)
str.slice(begin [, end])
:截取并返回对应字符串,不改变原字符串;str.splice(begin [, length])
:截取并返回对应字符串,改变原字符串;str.substring(begin [, end])
:参数小于0则会被设置为0,截取并返回对应字符串,不改变原字符串;str.split(separator [, num])
:字符串分割为数组;
- 可通过
str.split('k').length - 1
获得k
在字符串str
中出现的次数;
str.concat()
:字符串拼接;str.toLowerCase()
str.toUpperCase()
str.trim()
:去掉字符串首尾空格;
- 去除中间空格可通过
split()
分割后再拼接成字符串;
1.2 数组方法
arr.push()
arr.pop()
arr.unshift()
:将一个或多个元素添加至数组的开头,返回值是修改后的数组长度;arr.shift()
:将数组第一个元素删除,并返回被删除元素;空数组返回undefined
;arr.splice(start [, num, item1, item2...])
:包含添加、替换及删除方法;arr.sort((a, b) => (a - b))
:默认根据unicode排序;
a - b
若大于0,则b
排到a
前面,小于0相反,等于0则不变;
arr.concat()
arr.join()
arr.reverse()
arr.indexOf()
arr.lastIndexOf()
arr.slice()
arr.forEach()
arr.filter()
arr.map()
arr.reduce()
:数组累加arr.some()
arr.every()
1.3 对象语法
keys(obj)
:返回由对象key
组成的数组values(obj)
:返回由对象value
组成的数组delete obj[key]
1.4 Math 方法(内置对象)
提供了与数学相关的属性与方法
Math.PI
Math.ceil()
:向上取整Math.floor()
:向下取整Math.round()
:四舍五入,非数值返回NaN
Math.random()
Math.max()
:案例:Math.max(num, 0)
Math.min()
Math.abs()
3. ECMAScript 6 基础
1. JS三大部分:ECMAScript、DOM(文档对象模型)、BOM(浏览器对象模型);
2. var
、let
和const
:
-
var
:var
可以重复声明;- 作用域:全局作用域 和 函数作用域;
- 会进行预解析,变量提升;
-
let
:- 统一作用域下不能重复声明;
- 作用域:全局作用域 和 块级作用域
{}
- 不进行预解析;
-
const
:在let
的基础上:不能重新赋值;
3. 解构赋值:
- 对象:
{a, b} = obj
- 数组:
[a, b] = [b, a]
4. 展开运算符:...
let arr = [1, 2, 3, 4]
let obj = {
a: 1,
b: 2,
c: 3,
d: 4
}
let [ a, b, ...c ] = arr
let { a, b, ...c } = obj
//浅拷贝,只能深拷贝第一层
let arr2 = [...arr]
let obj2 = {...obj}
5. Set
对象:构造函数,用来构建某一类型的对象 - 对象实例化
//取重
let arr = [2,1,1,3,1,4,1,5,3]
let s = new Set(arr);
arr = [...s]
console.log(s.size) // size:数值的个数 ==> length
s.clear() //清空所有值
s.delete(2)
s.add(5)
s.has('a')
6. Map
对象
let arr = [
["a", 1],
["b", 2],
["c", 3]
]
console.log(m.size) // size:数值的个数 ==> length
m.clear() //清空所有值
m.get(key)
m.has(key)
m.delete(key)
m.set(key, val)
7. 函数新增扩展:箭头函数
- 箭头函数没有不定参
arguments
; - 箭头函数本身没有
this
,调用箭头函数的this
时,指向是其声明时所在作用域的this
;let fn = (num1, num2) => num1 * num2 console.log(fn(10, 30)) //不定参 let fn = (a, b, ...arg) => { console.log(arg) } fn(1,2,3,4)
8. 数组新增方法
-
Array.from(类数组)
:把一个类数组转换成真正的数组;
类数组:有下标有length; -
arr.find(callback[, thisArg])
:查找数组中满足要求的第一个元素的值;
arr.find(item => item >= 3)
-
arr.findIndex(callback[, thisArg])
:查找数组中满足要求的第一个元素的索引;
arr.findIndex(item => item >= 3)
-
arr.flat(index)
:多维数组扁平化处理; -
arr.flatMap((item, index) => {})
:多维数组扁平化处理; -
arr.fill(value[, start [, end]])
:数组填充; -
arr.includes(value[, start [, end]])
:判断是否包含检索值;
9. 字符串新增方法
-
str.includes()
-
str.startsWith()
-
str.endsWith()
-
str.repeat(index)
:重复当前字符串index
次; -
模板字符串:反引号``;
-
插值表达式:
${}
;
10. 对象新增方法
- 简洁表示法;
- 属性表达式;
Object.assign{ target, ...sources }
:对象合并;Object.is( value1, value2 )
:判断值是否相等;- 都是
undefined
; - 都是
null
; - 都是
true
orfalse
; - 都是由相同个数的字符按照相同顺序组成的字符串;
- 指向同一个对象;
- 都是数字且都是
+0
、-0
或者NaN
;
- 都是
11. Babel:JavaScript编译器
12. 模块化:解决变量污染
- 默认导出:
export default
,只能导出一个; - 导出:
export {a, b, c};
、export let d = 30;
- 导入:
script
标签声明type="module"
;
import {a, b, c} from '...';
import * as obj from '...';
13. 按需导入:优化性能
import("./a.js").then(res => { console.log(res); })
4. 面向对象
-
对象创建:字面量方式、构造函数、
Object.create()
(属性方法会放在原型上); -
对象调用
-
工厂模式:类的概念
//工厂模式 function Person(name, age, hobby){ let obj = {}; //添加原料 //加工 obj.name = name; obj.age = age; obj.hobby = function(){ console.log(hobby); } return obj; //出厂 } let zhangsan = Person("张三", 20, "喜欢篮球");
-
new
运算符- 执行函数;
- 自动创建一个空对象;
- 把空对象和
this
绑定; - 如果没有返还,隐式返还
this
function Test(){ // let obj = {}; === this; // return this; } new Test(); function Person(name, age, hobby){ // let obj = {}; //添加原料 === this; //加工 this.name = name; this.age = age; this.hobby = function(){ console.log(hobby); } // return obj; //出厂 } let zhangsan = new Person("张三", 20, "喜欢篮球");
-
构造函数
- 首字母大写;
this
指向实例化对象;- 静态属性和方法(属于类本身的);
-
优化构造函数性能:使用原型
prototype
——公共空间
-
构造函数
constructor
指向本身;function Person(name){ this.name = name; this.age = 20; } Person.prototype.hobby = function () { console.log("nothing"); } let zhangsan = new Person("张三"); // zhangsan.__protype__ === Person.prototype // Person.prototype.constructor === Person; // zhangsan.constructor === Person
-
__proto__
和constructor
属性是对象所独有的 -
prototype
属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__
和constructor
属性。
- 原型链:
Object.prototype.__proto__ === null
- 原型链查找规则:自下往上,就近原则;直到
Object.prototype
也找不到,返回undefined
; - 因此
Object.prototype
内添加属性或方法,可以被除null
和undefined
之外的所有数据类型对象使用。
call
、apply
及bind
-
call
:改变this
指向,接收多个参数; -
apply
:改变this
指向,只能接收数组参数; -
bind
:改变this
指向,并返回新的函数;function foo(name, age){ console.log(this, name, age); } let obj = { name: "张三"; } foo.call(obj, "张三", 20); foo.apply(obj, ["张三", 20]); foo.bind(obj)("张三", 20);
-
继承:
function Dad(name, age){ this.name = name; this.age = age; this.money = "100000"; } function Son(name, age){ //Dad.call(this, name, age); //Dad.apply(this, [name, age]); Dad.bind(this)(name, age); this.sex = "男"; } //这种方法不继承父类原型方法 let zhangsan = new Son("张三", 20); console.log(zhangsan.money)
-
传值和传址:
- 复杂数据类型传址:浅拷贝,内存地址一致;
- 简单数据类型传值:新开辟内存地址;
- 深拷贝:
JSON.parse(JSON.stringify(obj))
,缺点:丢失对象方法、undefined
;-
var clone = function (obj) { if(obj === null) return null if(typeof obj !== 'object') return obj; if(obj.constructor===Date) return new Date(obj); var newObj = new obj.constructor (); //保持继承链 for (var key in obj) { if (obj.hasOwnProperty(key)) { //不遍历其原型链上的属性 var val = obj[key]; newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合 } } return newObj; };
- 原型深拷贝:通过实例化开辟新地址
-
let Link = function () {} Link.prototype = Dad.prototype; Son.prototype = new Link(); Son.prototype.constructor = Son;
- ES6 中的类、原型写法
-
class Person { constructor(name, age){ this.name = name ; this.age = age; } //方法会自动写入原型内 action(){ console.log("走"); } }
- 静态成员:属于类本身的属性、方法;
//ES5 写法 Person.str = "数据"; //ES6 写法 class Person { static str = "数据"; } console.log(Person.str);
- ES6 继承:
-
class Dad { constructor (name, age) { this.name = name; this.age = age; } action(){ console.log("Dad"); } } class Son extends Dad { constructor (name, age) { //super继承必须写在前面 super(name, age); this.height = "178cm"; } action(){ super.action(); console.log("Son"); } }
- 单例模式:保证一个类只有一个实例;
-
//这种方法具有暴露风险性,一般通过函数构建返还 class Person{ static instance; constructor (name, age) { if(Person.instance){ return Person.instance; } Person.instance = this; this.name = name; this.age = age; } }
- 工厂模式
- 装饰者模式
-
Fucntion.prototype.DecorationFn = function(cb){ this.(); cb(); } obj.fire.DecorationFn (cb);
-
观察者模式:自定义事件
-
组件模块化
-
class Dialog{ constructor(options){ // 默认配置; let opts = { width: "30px", height: "250px", title: "测试标题", content: "测试内容", dragable: true, // 是否可拖拽 maskable: true, // 是否有遮罩 isCancel: false // 是否有取消 } // 合并配置; let newOpts = Object.assign(opts, options); // 相同键以后方对象为准 this.init(); } init(){ this.createHTML(); } createHTML(){ let dialogEle = document.createElement("div"); dialogEle.innerHTML = `...`; dialogEle.style.display = "none"; this.dialogEle = dialogEle document.querySelector("body").appendchild(dialogEle); } open(){ this.dialogEle.style.display = "block"; } } // 实例化 let dialog = new Dialog({ width: "40%", title: "我的标题" })
- 原生自定义组件
webcomponent
-
// 自定义组件 class MyCom extends HTMLElement{ constructor(){ super(); console.log(this); let div = document.createElement("div"); div.innerHTML = `<button>我是按钮</button>`; // 影子DOM let _sd = this.attachShadow({mode: "close"}); _sd.appendChild(div); } } customElements.define("my-com", MyCom);