JS高级-Promise使用详解
Promise的代码结构
我们来看一下Promise代码结构:
上面Promise使用过程,我们可以将它划分成三个状态:
待定(pending): 初始状态,既没有被兑现,也没有被拒绝;
当执行executor中的代码时,处于该状态;
已兑现(fulfilled): 意味着操作成功完成;
执行了resolve时,处于该状态,Promise已经被兑现;
已拒绝(rejected): 意味着操作失败;
执行了reject时,处于该状态,Promise已经被拒绝;
1234567891011121314151617181920// 1.创建一个Promise对象 const promise = new Promise((resolve, reject) => { // 注意: Promise的状态一旦被确定下来, 就不会再更改, 也不能再执行某一个回调函数来改变状态 // 1.待定状态 pending console.log("111111") console.log("222222") conso ...
JS高级-Proxy_Reflect使用详解
监听对象的操作
我们先来看一个需求:有一个对象,我们希望监听这个对象中的属性被设置或获取的过程
通过我们前面所学的知识,能不能做到这一点呢?
其实是可以的,我们可以通过之前的属性描述符中的存储属性描述符来做到; 监听对象的操作
下边这段代码就利用了前面讲过的 Object.defineProperty 的存储属性描述符来 对属性的操作进行监听。
但是这样做有什么缺点呢?
首先,Object.defineProperty设计的初衷,不是为了去监听截止一个对象中 所有的属性的。
我们在定义某些属性的时候,初衷其实是定义普通的属性,但是后面我们强 行将它变成了数据属性描述符。
其次,如果我们想监听更加丰富的操作,比如新增属性、删除属性,那么 Object.defineProperty是无能为力的。
所以我们要知道,存储数据描述符设计的初衷并不是为了去监听一个完整的对象。
Proxy基本使用
在ES6中,新增了一个Proxy类,这个类从名字就可以看出来,是用于帮助我们创建一个代理的:
也就是说,如果我们希望监听一个对象的相关操作,那么我们可以先创建一个代理对象(Proxy对象) ...
ES6~ES13新特性3
ES7-Array Includes
在ES7之前,如果我们想判断一个数组中是否包含某个元素,需要通过 indexOf获取结果,并且判断是否为 -1。
在ES7中,我们可以通过includes来判断一个数组中是否包含一个指定的元素,根据情况,如果包含则返回 true,否则返回false。
ES7–指数exponentiation运算符
在ES7之前,计算数字的乘方需要通过 Math.pow方法来完成。
在ES7中,增加了 ** 运算符,可以对数字来计算乘方。
ES8-Object values
之前我们可以通过 Object.keys获取一个对象所有的key
在ES8中提供了 Object.values来获取所有的value值:
ES8-Object entries
通过 Object.entries可以获取到一个数组,数组中会存放可枚举属性的键值对数组。
可以针对对象、数组、字符串进行操作;
123456789101112131415161718192021222324252627const obj = { name: "why", ...
ES6~ES13新特性2
Set的基本使用
Set是一个新增的数据结构,可以用来保存数据,类似于数组,但是和数组的区别是元素不能重复
创建Set我们需要通过Set构造函数(暂时没有字面量创建的方式):
我们可以发现Set中存放的元素是不会重复的,那么Set有一个非常常用的功能就是给数组去重。
Set的常见方法
Set常见的属性:
size:返回Set中元素的个数;
Set常用的方法:
add(value):添加某个元素,返回Set对象本身;
delete(value):从set中删除和这个值相等的元素,返回boolean类型;
has(value):判断set中是否存在某个元素,返回boolean类型;
clear():清空set中所有的元素,没有返回值;
forEach(callback, [, thisArg]):通过forEach遍历set;
另外Set是支持for of的遍历的。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253// 1.创建S ...
JS高级-ES13新特性1
let/const基本使用
let关键字:
从直观的角度来说,let和var是没有太大的区别的,都是用于声明一个变量;
const关键字:
const关键字是constant的单词的缩写,表示常量、衡量的意思
它表示保存的数据一旦被赋值,就不能被修改;
但是如果赋值的是引用类型,那么可以通过引用找到对应的对象,修改对象的内容;
注意:
另外let、const不允许重复声明变量;
12345678910111213141516171819// ES6开始 // 1.let let message2 = "你好, 世界" message2 = "你好, why" message2 = 123 console.log(message2) // 2.const // const message3 = "nihao, shijie" // message3 = "nihao, why" //报错 // 赋值引用类型 const inf ...
JS高级-ES6实现继承
对象的方法补充
hasOwnProperty
对象是否有某一个属于自己的属性(不是在原型上的属性)
in/for in 操作符
判断某个属性是否在某个对象或者对象的原型上
instanceof
用于检测构造函数(Person、Student类)的pototype,是否出现在某个实例对象的原型链上
isPrototypeOf
用于检测某个对象,是否出现在某个实例对象的原型链上
class定义类12345678910111213141516171819class Person { } // 创建实例对象 var p1 = new Person() var p2 = new Person() console.log(p1, p2) // 另外一种定义方法: 表达式写法(了解, 少用) var Student = class { } var foo = function() { } var stu1 = new Student() console.log(stu1)
类和构造函数的异同
我们来研究一下类的 ...
JS高级-ES5中实现继承
认识对象的原型
**JavaScript当中每个对象都有一个特殊的内置属性 [[prototype]],这个特殊的对象可以指向另外一个对象。 **
那么这个对象有什么用呢?
当我们通过引用对象的属性key来获取一个value时,它会触发 [[Get]]的操作;
这个操作会首先检查该对象是否有对应的属性,如果有的话就使用它;
如果对象中没有改属性,那么会访问对象[[prototype]]内置属性指向的对象上的属性;
那么如果通过字面量直接创建一个对象,这个对象也会有这样的属性吗?如果有,应该如何获取这个属性呢?
答案是有的,只要是对象都会有这样的一个内置属性;
获取的方式有两种:
方式一:通过对象的 proto 属性可以获取到(但是这个是早期浏览器自己添加的,存在一定的兼容性问题);
方式二:通过 Object.getPrototypeOf 方法可以获取到;
普通对象的原型
12345678910111213141516171819202122var obj = { name: "why", age: 18}console.log ...
JS高级-对象的增强知识
对属性操作的控制
在前面我们的属性都是直接定义在对象内部,或者直接添加到对象内部的:
但是这样来做的时候我们就不能对这个属性进行一些限制:比如这个属性是否是可以通过delete删除的?这个属性是否在for-in遍历的时候被遍历出来呢?
如果我们想要对一个属性进行比较精准的操作控制,那么我们就可以使用属性描述符。
通过属性描述符可以精准的添加或修改对象的属性;
属性描述符需要使用 Object.defineProperty 来对属性进行添加或者修改;
Object.defineProperty
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
可接收三个参数:
obj要定义属性的对象;
prop要定义或修改的属性的名称或 Symbol;
descriptor要定义或修改的属性描述符;
返回值:
被传递给函数的对象。
123456789101112131415161718192021222324var obj = { name: "why", // conf ...
JS高级-函数的增强知识
函数对象的属性
我们知道JavaScript中函数也是一个对象,那么对象中就可以有属性和方法。
属性name:一个函数的名词我们可以通过name来访问;
属性length:属性length用于返回函数参数的个数;
注意:rest参数是不参与参数的个数的;
认识arguments
arguments 是一个 对应于 传递给函数的参数 的 类数组(array-like)对象。
array-like意味着它不是一个数组类型,而是一个对象类型:
但是它却拥有数组的一些特性,比如说length,比如可以通过index索引来访问;
但是它却没有数组的一些方法,比如filter、map等;
123456 function foo(m, n) { // arguments 类似数组对象 console.log(arguments) }foo(10, 25, 32, 41)
arguments 遍历和转换成数组1234567891011121314151617function foo(m, n) { // 1.默认用法: ...
JS高级-内存管理和闭包
JavaScript的内存管理
JavaScript会在定义数据时为我们分配内存。
但是内存分配方式是一样的吗?
JS对于原始数据类型内存的分配会在执行时, 直接在栈空间进行分配;
JS对于复杂数据类型内存的分配会在堆内存中 开辟一块空间,并且将这块空间的指针返回值 变量引用;
常见的GC算法 – 引用计数 (不重要)
引用计数:
当一个对象有一个引用指向它时,那么这个对象的引用就+1;
当一个对象的引用为0时,这个对象就可以被销毁掉;
这个算法有一个很大的弊端就是会产生循环引用;
常见的GC算法 – 标记清除 (不重要)
标记清除:
标记清除的核心思路是可达性
这个算法是设置一个根对象(root object),垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,对于哪些 没有引用到的对象,就认为是不可用的对象;
这个算法可以很好的解决循环引用的问题;
闭包的定义
一个普通的函数function,如果它可以访问外层作用域的自由变量,那么这个函数和周围环境就是一个闭包;
从广义的角度来说:JavaScript中的函数都是闭包;
从狭义的角度来说:J ...