• js中高级部分知识点总结第二篇


    写几篇关于js部分的知识点,之前已经写过一篇了,但是因为js的内容比较多,所以慢慢的更新,之前的第一篇的文章篇幅比较大,导致很多人可能都不怎么看的完,所以后面的关于js方面的知识点,一篇文章就几个知识点就可以了,不用那么长,没啥实质性的作用,也不太好记,今天主要说一下关于对象,generator,symbol等知识点,后续的再说吧。

    关于js中对象的创建方式总结
    • 官方创建方法一
    let o = new Object()
    o.name = 'jim'
    o.func = function() {
    	console.log(o.name)
    }
    o.func()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 官方创建方法二
    let c = {
    	name: 'jim',
    	func: function() {
    		console.log(c.name)
    	}
    }
    let o4 = Object.create(c)
    c.func()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 常见的创建方法
    let o1 = {
    	name: 'jim',
    	func: function() {
    		console.log(o1.name)
    	}
    }
    o1.func()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 工厂模式创建
    function creatObj(params) {
    	let o = new Object()
    	o.name = params
    	o.func = function() {
    		console.log(o.name)
    	}
    	return o
    }
    let o2 = new creatObj('jim')
    o2.func()
    //缺点是: 
    console.log(o2 instanceof creatObj) //false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 构造函数创建
    function Co(params) {
    	this.name = params
    	this.func = function() {
    		console.log(this.name)
    	}
    }
    let o3 = new Co('jim')
    o3.func()
    console.log(o3 instanceof Co) //true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 类创建
    class Coj {
    	constructor(params) {
    		this.name = params
    		this.func = function() {
    			console.log(this.name)
    		}
    	}
    }
    let o5 = new Coj('jim')
    o5.func()
    console.log(o5 instanceof Coj) //true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    关于js中的防抖和节流

    js优化的方法中有一个不得不提的方式就是防抖和节流,今天我们就简单的说一下他的工作流程,首先说一下节流

    • 节流

    节流字面意思就是节省流动,这里的流动映射到js优化中可以简单的理解为操作,节流就是减少操作的进行,比如我们滚动页面的时候,如果不做节流的操作,假设我们滚动一次就请求一次函数,函数单一的还好, 如果函数本身就执行的比较麻烦的函数,这个时候我们的页面可能会出现卡死的情况,cpu也吃不消,这个时候我们需要的是,滚动的时候我们加个时间控制,不管你滚动的多快只要不超过我们设置的时间间隔,我都不给你执行即可,这个过程就是节流,那么代码实现就是通过一个闭包加上时间延迟进行实现。

    // 函数节流
    			let f = () => {
    				console.log('this is option logs')
    			}
    			function showLog(func, delay) {
    				let timer
    				return function() {
    					let that = this
    					let arg = arguments
    					if (timer) {
    						return
    					}
    					timer = setTimeout(function() {
    						func.call(that, arg)
    						timer = null
    					}, delay)
    				}
    			}
    			window.addEventListener('resize', showLog(f, 2000))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    这里不管你窗口放大缩小的多快,只要不超过2s,2s内你不停的执行我也只会2s执行一次,不会再不停地执行

    • 防抖

    防抖顾名思义就是防止抖动,点击一次时间之后进行计时,这个时间内,不进行再次操作,我们就执行函数,如果一直点击,时间就会一直被重置,那么函数就一直不会被执行,这个就是防抖的一个流程,这样做的好处就是比如付款的时候,不停地点击,可能会出现反复付款的情况,那么这个时候很容易出问题,防抖很大一部分应用场景是页面滚动和表单提交,所以这里写一个简单的demo

    const btn = document.querySelector('button')
    			let c = () => {
    				console.log('我被点击了')
    			}
    			let f = (c, dealy) => {
    				let timer
    				return function() {
    					let that = this
    					let arg = arguments
    					clearTimeout(timer)
    					timer = setTimeout(function() {
    						c.apply(that, arg)
    					}, dealy);
    				}
    			}
    			btn.addEventListener('click', f(c, 2000))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这样在2s内不管你点击多少次,我都只会在我的计时结束之后执行一次,就起到了防抖的效果。

    symbol

    一个永远都不会重复相等的基本数据类型,介绍完毕

    let i = Symbol()
    let j = Symbol()
    // console.log(i === j) //false
    
    • 1
    • 2
    • 3
    • 添加描述
    // 添加描述
    let s = Symbol('this is symbol')
    console.log(s) //Symbol(this is symbol)
    console.log(s.description) //this is symbol
    
    • 1
    • 2
    • 3
    • 4
    • 不同的定义方式,获取描述信息的方式相同
    let a = Symbol.for('this')
    let b = Symbol.for('this')
    console.log(a === b) //true
    //获取描述信息方式改变
    console.log(Symbol.keyFor(a)) // 这个只能是全局的for定义才是可以的, 普通的定义方式是没办法获取的
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用for来进行定义 使用for进行定义的时候,其实是在全局进行保存了一个值,这个时候我们重新定义了一个新的值的话,那么重要描述信息是一致的,就被当做一个同一个

    • 使用场景举例
    let obj = {
    	'jim': 'my name is jim',
    	'jim': 'my name is other jim'
    }
    console.log(obj) //{ jim: 'my name is other jim' }  后面的会覆盖前面的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    尝试解决
    let k1 = 'jim'
    let k2 = 'jim'
    let obj1 = {
    	k1: 'my name is jim',
    	k2: 'my name is other jim'
    }
    console.log(obj1) //{ k1: 'my name is jim', k2: 'my name is other jim' } 很明显key值不对
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    let k1 = 'jim'
    let k2 = 'jim'
    let obj1 = {
    	[k1]: 'my name is jim',
    	[k2]: 'my name is other jim'
    }
    console.log(obj1)  //{ jim: 'my name is other jim' }  后面的会覆盖前面的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    使用symbol解决
    let k1 = {
    	name: 'jim',
    	key: Symbol('jim')
    }
    let k2 = {
    	name: 'jim',
    	key: Symbol('jim')
    }
    let obj1 = {
    	[k1.key]: 'my name is jim',
    	[k2.key]: 'my name is other jim'
    }
    console.log(obj1[k1.key]) //my name is jim
    console.log(obj1[k2.key]) //my name is other jim
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 获取symbol的属性
    let sys = Symbol('this is symbol')
    let objf = {
    	name: 'jim',
    	[sys]: 'symbol'
    }
    for (let i in objf) {
    	console.log(i) // name 
    }
    for (let o of Object.keys(objf)) {
    	console.log(o) //name 
    }
    for (let o of Reflect.ownKeys(objf)) {
    	console.log(o) // name  Symbol(this is symbol)
    }
    for (let o of Object.getOwnPropertySymbols(objf)) {
    	console.log(o) //Symbol(this is symbol)
    }
    let keys = Object.keys(objf).concat(Object.getOwnPropertySymbols(objf))
    for (let i of keys) {
    	console.log(i) //name  Symbol(this is symbol)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 保护属性对象的作用
    let params = Symbol('this is symbol')
    class Info {
    	constructor(name) {
    		this.name = name
    		this[params] = 'sb'
    	}
    	getInfo() {
    		return `${this.name} + ${this[params]}`
    	}
    }
    let gi = new Info('wlm')
    console.log(gi.getInfo()) //wlm + sb 
    
    for (let i in gi) {
    	console.log(i) //name
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    模板字面量 (模板字符串)

    好处就是可以直接在js中写html代码,同时支持换行,插值等操作

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title></title>
    	</head>
    	<body>
    		<div id="content">
    		</div>
    		<script type="text/javascript">
    			let f = (...p) => {
    					for (let i of p) {
    						console.log(i) // 5,6,8,9,11
    					}
    				}
    				(() => {
    					let info = 'this is params'
    					let h2 = `

    这是被字面量填充进去的h1

    这是被字面量填充进去的h2

    这是被字面量填充进去的h3

    这是一个参数:${info}
    `
    let content = document.getElementById('content') content.append(h2) // f(3, 4, 5, 6, 7, 8) let a = 5, b = 6, c = 8, d = 9 // 和中间的符号没有关系 f`${a},${b},${c},${d},${a + b}` //['', ',', ',', ',', ',', ''] f`${a} + ${b} + ${c} + ${d} + ${a + b}` //['', ' + ', ' + ', ' + ', ' + ', ''] })() </script> </body> </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    Generator

    今天讲一下关于Generator的知识点,很多人可能用过但是也有一部分没有用过,今天就大概说一下,首先Generator也是一个函数,只是他比较特殊,不仅仅是写法特殊,同时他的运行过程设计的也比较特殊,他可以分段执行函数,终止函数,同时他的函数执行方式也和普通函数不一样,他需要通过next进行执行,中断函数需要通过yield进行,下面我们写一段代码,感受一下:

    function* gen() {
    	yield 'jim'
    	yield 'kim'
    	yield 'mary'
    	return 'tom'
    }
    let l = gen()
    console.log(l.next()) //{ value: 'jim', done: false }
    console.log(l.next()) //{ value: 'kim', done: false }
    console.log(l.next()) //{ value: 'mary', done: false }
    console.log(l.next()) //{ value: 'tom', done: true }
    console.log(l) //Object [Generator] {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    特性:
    • GENERATOR 用于异步编程
    • es6 新出来的 可以交出函数的执行权
    • 可以通过yield暂停执行状态
    • return value 和 done 分别表示 属性值和执行状态 done : true 和false true 表示已经执行结束 false 表示还没有执行结束
    • 通过next()进行函数的执行
    generator函数之间均存在独立的作用域,互相之间不做干扰
    function* count() {
    	let n = 0
    	yield n++
    	yield n++
    	yield n++
    	return n
    }
    let cn = count()
    let newCn = count()
    console.log(cn.next()) //{ value: 0, done: false }
    console.log(cn.next()) //{ value: 1, done: false }
    console.log(newCn.next()) //{ value: 0, done: false } // 他们之间是没有任何关联的,都是独立存在的函数,每一次的变量接收函数都是全新的
    console.log(cn.next()) //{ value: 2, done: false }
    console.log(cn.next()) //{ value: 3, done: true }
    // 已经执行结束 么有函数可以执行 underfined
    console.log(cn.next()) //{ value: undefined, done: true }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    generator函数传递参数的时候会将上一个yield的执行状态重置掉
    function* pf() {
    	let n = 0
    	let v = yield n + 40
    	console.log('v=' + v) //v=90
    	yield n++
    	console.log('n=' + n) //n=1
    	yield n++
    	console.log('n=' + n) //n=2
    	yield n++
    	yield n++
    	return n
    }
    let p = pf()
    console.log(p.next()) //{ value: 40, done: false }
    p.next(90)
    console.log(p.next()) //{ value: 1, done: false }
    console.log(p.next()) //{ value: 2, done: false }
    console.log(p.next()) //{ value: 3, done: false }
    console.log(p.next()) //{ value: 4, done: true }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可以看出 上面当我们传递一个90进去的时候,发现并没有发生相加的情况,因为此时的n + 40的状态已经被参数覆盖了,也就是说相加的操作已经不存在了,所以这里是覆盖的操作

    强调一下,这篇文章不是水文,就是单纯的想要将这些知识点总结一下给你们,毕竟没一个知识点都是可以单独拿出来写的,但是写到一篇文章里面这样你们就不用移步到别的地方了,这篇文章也算是对前面js高级部分没有总结完的做一个补充吧,后续再有的话,我会继续更新的。

  • 相关阅读:
    华为云云耀云服务器L实例评测|部署在线思维导图 SimpleMindMap
    流水的数字内容,铁打的内容风控
    软件测试技术之如何编写测试用例(5)
    Android 基础知识3-4 Activity的声明周期
    剑指 Offer 40. 最小的k个数【查找排序】
    xml学习
    生成树协议
    动手学习深度学习09----Softmax 回归 + 损失函数 + 图片分类数据集
    aarch64 python 3.6.8 pip install neutron
    Linux - 驱动开发 - RNG框架
  • 原文地址:https://blog.csdn.net/qq_41485414/article/details/126322771