目录
引用类型:proto(隐式原型)属性,属性值是对象函数:prototype(原型)属性,属性值是对象
person.prototype.isPrototypeOf(stu)
[Object.getPrototypeOf(Object)替换已不推荐的Object._ _ proto _ ](#Object.getPrototypeOf(Object)替换已不推荐的Object. _ proto _ _)
[Object.create(instance) 以一个现有对象作为原型,创建一个新对象](#Object.create(instance) 以一个现有对象作为原型,创建一个新对象)
2.类方法:构造函数.prototype.fun=function(){}
[2.原型链:Dog.prototype = Object.create(Animal.prototype)](#2.原型链:Dog.prototype = Object.create(Animal.prototype))
[3.修正prototype上的构造函数:Dog.prototype.constructor = Dog](#3.修正prototype上的构造函数:Dog.prototype.constructor = Dog)
[执行上下文/作用域:执行环境(变量+函数)存于 变量对象](#执行上下文/作用域:执行环境(变量+函数)存于 变量对象)
[全局执行上下文:this 指向window全局对象](#全局执行上下文:this 指向window全局对象)
查找不到:原型链undefined,作用域链ReferenceError
[全局环境(普通函数/匿名函数):window/undefined 严格模式](#全局环境(普通函数/匿名函数):window/undefined 严格模式)
[JS预解析/编译(变量提升):var、function变量 创建作用域](#JS预解析/编译(变量提升):var、function变量 创建作用域)
[闭包:函数返回函数,且子函数 调用 父级作用域的变量](#闭包:函数返回函数,且子函数 调用 父级作用域的变量)
不再使用/为空的引用未被移除:闭包/DOM移除,子节点引用没移除
垃圾回收:自动定期,不需要的引用设置为null
[引用/(Object)对象Set ,Map(键(string,symbol)/值对),Promise(解决回调地狱)](#引用/(Object)对象Set ,Map(键(string,symbol)/值对),Promise(解决回调地狱))
Map:任何值(函数、对象、基本类型)都可以作为键/值,size,可迭代,删减优化,
Object:键:String、Symbol,JSON序列化JSON.stringify()和解析JSON.parse()
因为没有function声明,所以没有原型prototype,所以不能作为构造函数
[rest 参数:...真正的数组](#rest 参数:...真正的数组)
[ES7 的async/await函数替代了ES6 的Generator 函数](#ES7 的async/await函数替代了ES6 的Generator 函数)
[字符串方法:{ },单反引号](#字符串方法:{ },单反引号)
[ES6 前作用域: 全局变量 与 函数内的局部变量。](#ES6 前作用域: 全局变量 与 函数内的局部变量。)
[const :必须初始化(语法错误SyntaxError),栈值/内存地址不变(类型错误TypeError)](#const :必须初始化(语法错误SyntaxError),栈值/内存地址不变(类型错误TypeError))
Number(任意类型):若string含非数字,会返回NaN
parseInt(string[,radix]):基数radix是2-36之间的整数
parseFloat(string):解析一个参数并返回一个浮点数
[str - 1 //122](#str - 1 //122)
[+str+1 // 124](#+str+1 // 124)
[str+1 // '1231'](#str+1 // '1231')
[Boolean():0, ''(空字符串), null, undefined, NaN会转成false,其它都是true](#Boolean():0, ''(空字符串), null, undefined, NaN会转成false,其它都是true)
[隐式转换 :!!](#隐式转换 :!!)
[typeof:判断 基本数据类型](#typeof:判断 基本数据类型)
[typeof null=Object 类型标签均为000](#typeof null=Object 类型标签均为000)
[实例 instanceof 构造函数:判断原型链,和isPrototypeOf](#实例 instanceof 构造函数:判断原型链,和isPrototypeOf)
[构造函数.prototype.isPrototypeOf(实例) :判断原型链](#构造函数.prototype.isPrototypeOf(实例) :判断原型链)
[(数据).constructor === 数据类型:不包含继承类型](#(数据).constructor === 数据类型:不包含继承类型)
[显示:toString,valueOf 除了null,undefined](#显示:toString,valueOf 除了null,undefined)
[valueOf:this 值转换成对象。除了Date都是返回数据本身](#valueOf:this 值转换成对象。除了Date都是返回数据本身)
toString:重写对象的类型转换。console.log
[松散相等==(可自动转换类型) 和 严格相等===](#松散相等==(可自动转换类型) 和 严格相等===)
[for of:val,Object.keys(obj)自身属性](#for of:val,Object.keys(obj)自身属性)
[for in:idx ,包括继承的可枚举属性](#for in:idx ,包括继承的可枚举属性)
[可遍历对象的 公有 可枚举属性(除symbol 属性)](#可遍历对象的 公有 可枚举属性(除symbol 属性))
[obj.hasOwnProperty(prop) 避免遍历原型链上的属性](#obj.hasOwnProperty(prop) 避免遍历原型链上的属性)
forEach(value[,index,arr]):不改变原数组,返回undefined
[无法中断( break (Illegal break statement)和 return (无效))](#无法中断( break (Illegal break statement)和 return (无效)))
[高阶函数:params / return func](#高阶函数:params / return func)
[函数柯里化:return func](#函数柯里化:return func)
改变数组:进出*4,splice,sort,reverse,fill
[typeof this !== 'function'](#typeof this !== 'function')
[context = context || window](#context = context || window)
[context._this = this](#context._this = this)
[delete context._this](#delete context._this)
[bind: return _this.apply(context, [...arguments].slice(1));](#bind: return _this.apply(context, [...arguments].slice(1));)
[!arr|| arr == null || typeof arr != 'object'](#!arr|| arr == null || typeof arr != 'object')
[arr instanceof Array ? [] : {}](#arr instanceof Array ? [] : {})
[result[key] = cloneDeep(arr[key])](#result[key] = cloneDeep(arr[key]))
原型链
引用类型:
__proto__(隐式原型)
属性,属性值是对象
函数:prototype(原型)
属性,属性值是对象
相关方法
person.prototype.isPrototypeOf(stu)
Object.getPrototypeOf(Object )替换已不推荐的Object._ _ proto _ _
Object.create(instance) 以一个现有对象作为原型,创建一个新对象
class类
ES6前:构造函数和原型链
1.构造函数:this.x=x
2.类方法:构造函数.prototype.fun=function(){}
继承
1.构造函数:父类构造函数.call(this,x)
2.原型链:Dog.prototype = Object.create(Animal.prototype)
3.修正prototype上的构造函数:Dog.prototype.constructor = Dog
javascript
// 使用构造函数和原型链定义"类"
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + ' makes a sound.');
};
// 创建类的实例
const dog = new Animal('Dog');
dog.speak(); // 输出: "Dog makes a sound."
// 继承一个"类"
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
//Object.create() 静态方法以一个现有对象作为原型,创建一个新对象
Dog.prototype = Object.create(Animal.prototype);
//修正构造函数
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
console.log(this.name + ' barks loudly.');
};
const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.speak(); // 输出: "Buddy barks loudly."
ES6:class
constructor可没有(默认会创建)
super必须实现
执行上下文 /作用域:执行环境(变量+函数)存于 变量对象
全局 执行上下文:this 指向window全局对象
函数 执行上下文:每次调用会创建新的执行上下文
作用链=作用域链表
查找不到:原型链undefined,作用域链ReferenceError
this
全局 环境(普通函数/匿名函数):**window/**undefined 严格模式
调用函数的对象
JS预解析/编译(变量提升):var、function变量 创建作用域
闭包:函数返回函数 ,且子函数 调用 父级作用域的变量
因为js作用域生命周期 在于内部脚本是否全部执行完毕才会销毁 ,并且不会带到父级作用域;
因为被下级作用域内 引用 ,而没有被释放 。就导致上级作用域内的变量,等到下级作用域执行完后 或者 当闭包(子函数)不再被引用 时才会被释放。
javascript
function createCounter() {
let counter = 0
const myFunction = function() {
counter = counter + 1
return counter
}
return myFunction
}
const increment = createCounter()
const c1 = increment()
const c2 = increment()
const c3 = increment()
console.log('example increment', c1, c2, c3)//1 2 3
- 闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包
- 滥用闭包容易内存泄漏。
- 使用场景 : 防抖、节流 、函数套函数 避免全局污染
内存泄漏:内存浪费->慢->崩溃
不再使用/为空的引用未被移除:闭包/DOM移除,子节点引用没移除
垃圾回收:自动定期,不需要的引用设置为null
(GC)Garbage Collection
浏览器 的js 具有自动 垃圾回收机制,垃圾回收机制 也就是自动内存管理 机制,垃圾收集器会定期 的找出不可访问的值 ,然后释放内存,所以将不需要的对象设为null即可。
模块化规范 :一个模块=实现特定功能 的一组方法。
几个函数: 全局变量的污染 ,模块间没有联系。
javascript
// 模块A
var ModuleA = {
func1: function() {
// ...
},
func2: function() {
// ...
}
};
// 模块B
var ModuleB = {
func3: function() {
// ...
}
};
- 后面提出了对象,通过将函数作为一个对象的方法 来实现,但是这种办法会暴露 所 有的所有的模块成员,外部代码可以修改内部属性的值。
- 现在最常用的是立即执行函数 的写法,通过利用闭包 来实现模块私有作用域 的建立,同时不会对全局作用域造成污染。
javascript
//IIFE(立即调用函数表达式)
//创建一个私有作用域,避免变量之间的冲突。然后,通过返回一个对象或函数来暴露模块的公共部分
// 模块A
var ModuleA = (function() {
var privateVar = "private";
function privateFunc() {
// ...
}
return {
publicVar: "public",
publicFunc: function() {
// ...
}
};
})();
- ES6 :使用import 和 export的形式来导入导出模块。
ES6新增
数据类型:
基本Symbol,Bigint(ES10)
javascript
let bnum=1684424684321231561n //方式1:数组后加n
bunm=BigInt("1684424684321231561")//方式2:调用BigInt
引用/(Object)对象Set ,Map(键(string,symbol)/值对),Promise(解决回调地狱)
WeakSet:
弱引用(不被引用时会被回收)对象
WeakMap
: 键(弱引用对象)/值对
Map:
任何值 (函数、对象、基本类型)都可以作为**键/值,**size,可迭代,删减优化,
Object
:键:String 、Symbol, JSON序列化JSON.stringify()和解析JSON.parse()
运算符
变量 的解构赋值: 从数组/对象中取值
javascript
// 提取部分数组元素,其余元素放在剩余数组中
const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers;
console.log(first); // 输出: 1
console.log(second); // 输出: 2
console.log(rest); // 输出: [3, 4, 5]
// 从对象中提取属性并赋值给变量
const person = { firstName: 'John', lastName: 'Doe' };
const { firstName, lastName } = person;
console.log(firstName); // 输出: John
console.log(lastName); // 输出: Doe
// 提取属性并赋值给变量,并指定默认值
const { age = 30, occupation = 'Engineer' } = person;
console.log(age); // 输出: 30 (因为age属性不存在)
console.log(occupation); // 输出: Engineer (因为occupation属性不存在)
const nestedObject = {
outer: {
inner: {
deep: 'Hello, nested!'
}
}
};
const { outer: { inner: { deep } } } = nestedObject;
console.log(deep); // 输出: Hello, nested!
数组/对象 :扩展运算符(浅拷贝)
函数
箭头函数:简洁
继承上一层作用域链的this
不绑定arguments ,用rest参数
因为没有function声明,所以没有原型prototype,所以不能作为构造函数
rest 参数:...真正的数组
javascript
function sum(...numbers) {
let total = 0;
for (let number of numbers) {
total += number;
}
return total;
}
console.log(sum(1, 2, 3)); // 输出 6
ES7 的async/await函数替代了ES6 的Generator 函数
字符串方法:${ },单反引号
块级**作用域:**let,const
ES6 前作用域: 全局变量 与 函数内的局部变量。
**块级作用域{}:**if(){},for(){}等
var:重复 声明,变量提升
let、const:块作用域 里访问,无重复声明,变量提升
const :必须初始化( 语法错误SyntaxError**)** ,栈值/内存地址不变(类型错误TypeError)
定义类的语法糖(class)
模块化import/export
类型转换
Number
显式类型转换
Number(任意类型):若string含非数字,会返回NaN
parseInt(string[,radix]):基数radix是2-36之间的整数
parseFloat(string):解析一个参数并返回一个浮点数
隐式转换:+str-,含boolean的相加
str = '123'
str - 1 //122
+str+1 // 124
str+1 // '1231'
string
显式类型转换
除了null/undefined.toString()
String(任意类型)
隐式转换:含str的相加
Boolean
显式类型转换
Boolean():0, ''(空字符串), null, undefined, NaN会转成false,其它都是true
隐式转换 :!!
判断数据类型
运算符
typeof:判断 基本数据类型
typeof null=Object 类型标签均为000
实例
instanceof 构造函数
:判断原型链,和isPrototypeOf
javascript
Object.prototype.isPrototypeOf({})// true
{} instanceof Object// true
方法
构造函数.
prototype.isPrototypeOf(实例)
:判断原型链
(数据 ).constructor === 数据类型:不包含继承类型
显示:toString,valueOf 除了null,undefined
valueOf:this
值转换成对象。除了Date都是返回数据本身
console.log
toString:重写对象的类型转换。console.log
松散相等==(可自动转换类型) 和 严格相等===
比较的是内存单元的内容
set判断===相等
javascript
//Set用===判断是否相等
const set= new Set();
const obj1={ x: 10, y: 20 },obj2={ x: 10, y: 20 }
set.add(obj1).add(obj2);
console.log(obj1===obj2);//false
console.log(set.size);// 2
set.add(obj1);
console.log(obj1===obj1);//true
console.log(set.size);//2
DOM事件流:捕获->冒泡
- 事件捕获 :由外往内,从事件发生的根节点 开始,逐级往下查找,一直到目标元素。
- 事件冒泡 :由内往外,从具体的目标 元素触发,逐级向上传递,直到根节点。
javascript
element.addEventListener(event, function[, useCapture]);
//useCapture 默认为false,即冒泡阶段调用事件处理函数,
//为ture时,在事件捕获阶段调用处理函数
遍历(str,num,set,map)
for of:val,Object.keys(obj)自身属性
for in:idx ,包括继承的可枚举属性
可遍历对象 的 公有 可枚举属性(除symbol 属性)
obj.hasOwnProperty(prop) 避免遍历原型链上的属性
forEach(value[,index,arr]):不改变原数组,返回undefined
无法中断**(** break (Illegal break statement)和 return (无效))
map(value[,index,arr]):返回新的数组
执行速度优于forEach(底层做了优化)
高阶函数:params / return func
函数****************************柯里化:return func
改变数组:进出*4,splice,sort,reverse,fill
手写
改变this
call
typeof this !== 'function'
context = context || window
context._this = this
delete context._this
javascript
// 给function的原型上面添加一个 _call 方法
Function.prototype._call = function (context) {
// 判断调用者是否是一个函数 this 就是调用者
if (typeof this !== 'function') {
throw new TypeError('what is to be a function')
}
// 如果有 context 传参就是传参者 没有就是window
context = context || window
// 保存当前调用的函数
context._this = this
// 截取传过来的参数
/*
arguments
a: 1
fn: ƒ fns()
*/
// 通过 slice 来截取传过来的参数
const local = [...arguments].slice(1)
// 传入参数调用函数
let result = context._this(...local)
// 删属性
delete context._this
return result
}
let obj = { a: 1 }
function fns(a, b) {
console.log(a, b);
console.log(this)
}
fns._call(obj, 23, 555)
bind: return _this.apply(context, [...arguments].slice(1));
深拷贝
!arr|| arr == null || typeof arr != 'object'
arr instanceof Array ? [] : {}
for (const key in arr)
result[key] = cloneDeep(arr[key])
javascript
function cloneDeep(arr = {}) {
// 终止递归
if (!arr|| arr == null || typeof arr != 'object' ) return arr
// 用 instanceof 判断原型链上是否有该类型的原型 是 Array => [] ! Arrays =>{}
let result=arr instanceof Array ? [] : {}
// forin 循环对象的key值
for (const key in arr) {
// 对象 key 赋值 result
result[key] = cloneDeep(arr[key])
}
return result
}