javascript 拾遗

基本吹牛逼类型

基础概念
	1.ECMAscript 是 javascript 的标准  javascript  是 ECMAscript 的实现

js基础知识

js的数据类型

1.js一共有 8 种数据类型 es5 6 种 后面又添加了 2 种
	1.Undefined String Symbol Object Null Number Boolean BigInt
	2.Number
		1.Number.MAX_VALUE,Number.MIN_VALUE
2.检查数据类型
	1.typeOf 会返回 string number function boolean
			1.number
				1.NaN not a number typeOf(NaN) 返回 Number
				2.Infinity -Infinity 分别表示正无穷 和 负无穷 typeOf(Infinity) 返回 Number
		1.typeOf [] {} null 都是 object
		2.typeOf undefined 返回 undefined
		3.type Symbol("a") 返回 symbol
		4.type BitInt(5) 返回 bigint
		3.typeOf 总共返回 8 钟类型标识
	2.Object.prototype.toString.call([])
		1.[object Null]/[object Undefined]/[object Function]/[object String]
		2.[object Number]/[object Symbol]/[object BigInt]/[object Array]
3.数据类型转换
	1.转换为 string
		1.a.toString
			1.对于 null 和 undefined 不会调用toString 而是内部 直接 转为 "null" "undefined"
		2.String(a)
		3.转为字符串 123 + "a" 先把123转为字符串 + ”a“ -> "123a"
	2.转 number
		1.Number("12") 12 纯数字 直接转化为数字
		2.Number("") Number("   ") 空字符串 含空格也一样 转换为 0
		3.Number("123px") 稍有不行 转为 NaN
			console.log(Number(undefined)) //NaN
			console.log(Number(NaN)) //NaN
			console.log(Number({})) //NaN
			console.log(Number(function(){})) //NaN
			console.log("---------------------------")
			console.log(Number(true)) //1
			console.log(Number(false))//0
			console.log(Number("123"))//123
			console.log(Number("    "))//0
			console.log(Number([]))//0
			console.log(Number(null))//0
			console.log(+"123")//123
			console.log({} == "[object Object]")//true 说明{}调用了 toString() 方法
			console.log(0+"123")//"0123"
				1.一元运算符 + 可以转为为数字 也是调用 Number
				2.0 + ”123“ -> "0123"
		4.parseInt("123px") 123
			0.对于 非 string 的类型转换为 先转换为 string 再进行 解析
			1.parseInt(true) -> parseInt("true") -> NaN
		5.parseFloat
		6.数据的表示种类
			1.十进制 12
			2.十六进制 0xaf
			3.八进制 07
			4.二进制 0b011
			5.转换的时候可以指定进制 parseInt(a,8) 把 a 转为为 8 进制
		7."123" * 1 -> 123 过程 Number("123") -> 123
			1.+ - * / % 任何操作符操作 除了 + 遇到 字符串 转换为字符串 其他的任何运算符号 都转换为 数字运行
			2.转换过程 Number() true + true = 2
			3."123" - 1 = 122
	3.boolean
		1.以下 6 种 false 类型
			1.fasle
			2.0
			3.空字符串”“ ” “ 有空格都不行 空格都是true
			4.null
			5.undefined
			6.NaN
	4.数组 array
		1.方法
			1.遍历方法
				1.forEach(function(item,index,this){})
					总的遍历方法:
					1、经典遍历方法:for语句、forEach语句、for-in语句、for-of语句
					2、其它循环方法:map(映射)方法、filter(过滤)方法、every方法、some方法、reduce方法(reduceRight)
					3、不常用的方法:find方法、findIndex方法
					4、ES6提供的三个新方法:keys方法、values方法、entries方法
					5.遍历速度for > for-of > forEach > filter > map > for-in>every>some
			2.能改变数组本身的方法 
				1.push pop unshift shift splice sort reverse
			3.常见难以理解的数组方法
				1.reduce((init,item,index,arr) => {return init + item})
					0.直接从第二次循环开始 赋值给 item 第一次循环默认已经把数值给了 init
					1.return 返回的结果 作为 下一次 init 的数值
					2.当到数组的最后一个之后 init 不再接受 return 的结果 结果 会作为 reduce 的函数返回值
					3.像上面 reduce 的结构就可以求一个数组的和
				2.如果不想让第一个元素作为init的数值 指定初始值  reduce((init,item,index,arr) => {return init + item},initV)
					1.指定了初始值后 第一个元素也参加循环 会赋值给 item,index
			4.arr.find(item => return ture) 返回结果是当前找到的元素 找到后 后面的不再执行 和 forEach 不同
				1.arr.findIndex(item => return ture) 和 arr.indexOf 类似 只不过 一个支持回调
		2.关于数组方法的返回数值
			1.返回 undefined
				1.forEach // undefiend 目的循环每个项目 比如给 每个元素 加一个 onlclick 方法
			2.返回新数组的有
				1.filter map 
					1.对于filter(fn) 参数必须为 函数 函数返回为 真 当前 item 就留下 如果要过滤掉 数组中 为假的
					2.[6种 0 "" false null undefined,NaN] arr.filter((item) =>{return item}) 这里的 item 会被转为 Boolean
					3.比如数组 arr = ["a",[]," ",null,"",0,NaN,false,undefined] // [ 'a', [], ' ' ] 6种假全部干掉
					4.还有一种简单的处理方式  arr.filter(Boolean) 直接把 构造函数传进去 妙不可言啊
			3.返回 boolean 的
				1.includes some every
					1.some 遇到就 return true 就停止 every 遇到 false 就停止 [省去了判断要let flag = true]
			4.返回一个计算数值
				1.reduce reduceRight indexOf find findIndex
		3.无法阻止数组的遍历 即使 rturn
			1.map forEach reduce reduceRight
	5.包装类
		1.String Number Boolean 可以把基本数据类型转换成包装类 var n = 3;无法添加属性方法 n = New Number(n); 可以添加
			1.显示转换是可以添加的 隐式的不行
		2.但是 当 基本数据类型去调用方法时候 js做了一个隐式的 临时包装类转换 方法执行完毕后 对象销毁 又转换为 临时类型
		3.let n = 3; n.hello = "hello" ,console.log(n.hello) //读不出来的 发生了 两次包装类转换
			1.当添加 hello 时候 n会转换为 对象 添加了 该属性 然后对象销毁 同时转换为 基本数据类型
			2.当读 n.hello 的时候 再次转换为对象 去读发现并没有添加 hello 对象 [因为添加的那个已经销毁了] 于是读 n.hello
			3.结果 undefined 因为该临时对象 不是添加时候的那个对象了 读完后 再次转换为 基本数据类型
	6.字符串方法
		1.charAt 返回索引字符 charCodeAt 返回索引对应的字符编码 fromCharCode 从字符编码返回字符 比如 String.fromCharCode(65) A
		2.字符串和正则相关的方法
			1.split(//) search() match() replace()
			2.search
				1.返回搜到第一次出现的位置 就像 indexOf
			3.match 返回结果数组
				1.str.match(/a(b)c/i) 搜索不动返回 null 如果不带g 搜索到的带 子匹配 0 是匹配结果 1 2 3 都是子匹配
				2.如果带了 //ig 就没有子匹配 返回时 null 或者  1 2 3 都是 完整匹配结果
			4.replace
				1.replace(//ig,"aa")
				2.str.replace(regexp|substr, newSubStr|function)
		3.indexOf includes
		4.sustr(start,length) substing(start,end)
			1.substr start 可为负 length <=0 length  返回空 字符串
				1.如果 length 被忽略 默认从 start 开始 最大长度
			2.substring start end  可换位置 小的在前 大的在后
				1.写一个参数 默认到最尾巴
				2.如果 参数 是 负数 或 NaN 当作 0
				3.左闭右开

运算符

1.运算符
	1.++ 和 -- /// let a = 1; a++ + ++a + a /// 结果是1 + 3 + 3 =7
		1.let d = 1;d = d++;console.log(d) // 1 怎么理解呢 相当于 e = d++; d = e; e 很明显是 1 又赋值给了 d
		2.a++ ++a 都会使a数值立即改变 不同的是 a++ 返回旧数值 ++a 返回新数值
	2.逻辑运算符
		1.!取反 !!转逻辑
		2.if([] == "") 结果是 true 先转换为数值 再比较
	3.比较运算符
		1.a >= b <= > < 这些 
			1.如果 a b 类型相同 直接比较
			2.如果类型不同 都是先将 a 和 b 通过 Number 转为数值型 进行比较
		2. == 的比较
			1.注意 == 的比较 转换比较复杂 两边类型相同 直接比较
			2.如果两边类型不同比较麻烦
				0.null == undefiend --> true 但是null/undefined和任何值都不相等
				1.null和undefined是相等的 要比较相等性之前,不能将null和undefined转换成其他任何值
				2.如果有一个操作数是NaN,则相等操作符返回false 而不相等操作符则返回true 数都是NaN,相等操作符也返回false
				3.如果两个操作数都是对象,则比较他们是不是同一个对象。指向同一个对象,则相等放回true,否则返回false
					1.所以 {} == {} 返回 false
				4.如果由一个操作数是布尔值 则在比较相等性之前先将其转换为数值---false转换为0,而true转换为1
				5.如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值
					1.如果有一个是字符串 另一个不是数值和布尔值 则要转为字符串 比如 [] == "" [] 调用 toString 转为 "" 所以true
					2.再比如 {} == "" {}.toString() "[object Object]" 字符串 所以 false
				6.如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较
	4.三元运算符
		1.如果用三元运算符求三个数的最大数
			1.var max = a > b ? (a > c ? a : c) : (b > c ? b : c) //去掉括号也是没有问题的
				1.过程 如果 a > b 再 比较 a 和 c , 如果 b 大 比较 b 和 c 还是按从 前 到 后 的顺序计算的
	5.运算符优先级
		1.() [++ -- ! + -][+-*/%][> >= < <=][== === != !===][&& ||][=][,]
		2.大脑袋下 杀伐一天 争大小 拍次序[相等] 组后108将联合 赋值输出 逗号
	6.检查对象是否是构造方法的实例
		1.instanceof [dog instanceof Dog]
		2.hasOwnProperty 看是否对象自己的方法或者属性 不是 prototype 上面的

编码相关

1.console.log("\u2368") \u里面是 16 进制的数字 console.log("&#96854;") 这里的数字是十进制 换算后 可以表示同一个字符
	1.这里的参数是 字符串
2.String.fromCharCode(0x2692) 这的参数是整数型

this相关

1.函数调用方式 this 都是指向 window
2.方法调用方式 指向对象 本身
3.fn.call(this,a,b,c) fn.apply(this,[])
4.fn.bind(obj,a)
	1.返回一个新的函数 改变了 this 指向 obj 并且 固定第一个参数 比如 function fn(a,b,c){} ;let newFn = fn.bind(ojb,1)
	2.newFn(b,c) a 这个参数定死了 就是 1 了
5.对于 箭头函数没有自己的this 它的this 永远是定义环境的 外部 this 没法用 call apply bind 调用
	1.另外箭头函数也没有 arguments

对象相关

1.创建对象的方法
	1.字面量 let obj = {name:"zs"}
	2.工厂模式 function createObj(name){let obj = new Object(); obj.name = name; return obj}
		1.构造函数 都是 Object 不方便区分不同的类型对象
	3.构造函数 function Obj(name){this.name = name;} ojb = new Obj("zs");
		1.new 构造函数执行流程 [直接翻译 绝对靠谱]
			1.立即创建一个对象 称为新对象
			2.将构造函数的 prototype 属性 设置位新对象的原型
			2.以实参来执行构造函数 并将新对象设置为 函数中的 this
			3.如果构造函数 返回的是一个 对象[非基本类型] 那么该对象会作为该构造函数的返回值 [除非脑袋被驴踢了]
				1.否则 如果返回的是 基本类型 或者 没有返回值[默认返回undefined 也是基本类型] 则将新对象返回
	3.语法糖 ES6 class
2..关于 对象原型 prototype
		1.dog.__proto__ = Dog.prototype
		2.Dog.prototype.say(){console.log(this)} // 这里面的 this 就是每次的对象实例
		3.p1.__proto__.__proto__.__proto__ 最后Object 的 prototype 为 null
		4.p1.__proto__.__proto__ == Person.prototype.__proto__//true

正则表达式相关

1.var reg = new RegExp("\\d","ig") // 注意这里的 \需要转义
	1.参数解释
		1.i 忽略大小写 g 全局
2.字面量的方式
	1./\d/ig
3.正则常用方法
	1.reg.test 检查是否匹配
4.正则元数据
	1.[A-z] 全部字母
3.

元素的位置相关

1.clientX clientY offsetLeft offsetTop
	1.oL = e.clientX - obj.offsetLeft   oT = e.clientY - obj.offsetTop  鼠标点击瞬间 鼠标距离 左上角的位置
2.offsetWidth: border-box 包括滚动条
3.clientWidth: padding-box
4.scrollWidth: padding-box 包含视窗之外 scrollHeight = clientHeight + scrollTop [scrollTop 的最大距离]
5.offsetLeft/Top:元素相对于父窗口的偏移距离,父窗口的position没有绝对定位的情况
6.clientLeft/Top:元素的内外边距距离,通常就是边框宽度
7.scrollLfet/Top:滚动条滚动的距离
	1.oIn.scrollTop = oIn.scrollHeight - oIn.clientHeight //scrollTop 的最大数值

image

杂项

特殊的事件[scroll wheel]

1.scroll 表示滚动条的事件 拉动滚动条会触发 鼠标滚轮不一定动  wheel 表示鼠标滚轮事件
	1.scroll 不受事件回调的影响 但是 wheel 受回调影响
	2.所谓受回调影响 是指在 触发事件时候 做了浪费事件的事 比如 输出1万次abc Vue 事件修饰符 .passive 就是处理这个问题的

for 循环中 var 和 let 的理解

1.var 每次循环相当于 var i = 0; var i = 1 由于 var 重复声明被忽略 也不报错 同时 var 没有作用域的概念 于是 i 就相当于全局的变量
	1. 于是如果 异步调用i比如 setTimeout(function()(console.log(i))) 打印的 都是最后循环完毕的 全局变量 i
2.let 不同 虽然也是每次循环 let i = 0; let i = 1  但是 let 有 大括号作用域的概念 于是每次 回调函数 都有自己的作用域
3.在这里要注意的是 如果把  var 初始到外部 结果是不同的
	1.var i=0/let i=0 for(; i < 10; i++ ) 这样 i 无论是 var 还是 let 都是全局的 回调都会访问 最后的 10 全局的 i
	2.所以 对于 var 初始化 i 写在 for 内外 无影响 但是对于  let 写内外有本质不同 写内 相当于 let i = 0; let i = 1
	3.写外相对于 let i = 0  for 内部循环的时候  i = 1 / i = 2 只是去改变全局变量而已

不常见的dom操作

1.div.insertAdjacentElement("beforebegin","<div/>")
	1.把文本解析位dom元素并插入 参数有
		1.beforebegin afterbegin beforeend afterend // 元素本身前 元素内第一个子前 元素内最后一个 元素本身后

js Dom 各种事件的特征

1.键盘事件
	1.keydown keyup
		1.e.keyCode e.key 该事件需要绑定在 input:text 之类的有焦点的元素 或者 document
		2.

js文件加载时机

1.先后顺序
	1.script 标签写到 body最后
	2.window.onload 事件 等所有dom加载完毕 包括 iframe 里面的
	3.document 的 DOMContntLoaded事件 只等待本文档 不管 iframe 时机早于 onload
	4.给外部文件加 defer 时机早于 DOMContentLoaded

保留小数位数

1.floor ceil round[四舍五入] trunc[保留整数位]
2.num.toFixed() 没有参数 取整数 num.toFixed(3) 四舍五入保留三位小数
###鼠标捕获
	1.obj.setCapture() obj.releaseCapture
### Location
	1.Location.href = ""
	2.location.reload() 刷新 location.reload(true) 强制刷新 等同于ctrl + F5 
	3.localtion.assign("www.baidu.com")
	4.location.replace("www.baidu.com") //没有历史 不能退回

时间相关

1.Date.now() 返回当前的 13 位 时间戳 // +new Data() 同样的效果
2.new Date().getTime() 返回这个日期对象 对应的时间戳

结构化赋值

1.数组的结构化赋值
	1.[a,b,...c] = [1,2,3,4,5]
	2.利用结构化赋值交换两个数字 不需要引入第三个变量
		1.let a = 3; b=5; [a,b] = [b,a]
		2.let arr = ["zs","ls"]; [arr[0],arr[1]] = [arr[1],arr[0]]
2.对象的结构化赋值
	1.let {name,age} = p1;//声明并结构化赋值
	2.let name,age; ({name,age}) = p1 // 先声明 再赋值的化 必须加 () 防止认为是代码块
	3.好像对象结构化赋值没有数据方便 必须 name,age 如果想结构化赋值给 a b 呢 let {name:a,age:b=18} = p1;

深浅复制对象和数组

1.浅复制
	1.let destObj = Object.assign({}/[],OriObj)
	2.利用 数组的 arr.slice(0) 或者 arr.slice() 一样 可以对数组进行复制
2.深复制
	1.let destObj = structuredClone(OriObj)
	2.利用JSON

对象和Mab有什么不同

1.对象只可以用 字符串和符号作为键值 {"name":"zs",[Symbol("hh")]:"hh"} 凡是不是字符串的 都需要加 []
	1.如果一定要利用对象 作为键值 {[obj]:18} 会自动被转化为 {"object Object":18} 也就是说 obj[{}] 也可以访问到 尴尬不?
1.Map 为了突出自己的与众不同 长度用size 添加属性用 m.set(key,value)
	1.map 可以让任何类型作为 key 包括对象 甚至 NaN
3.map 和 数组的 关系
	1.let arr1 = Array.from(map) 会转换为 一个 二维数组 一维数组中 每个元素都是 一个 长度为 2 的 数组 
		1.为什么不能转为对象呢 多方便 数组多么别扭 那是因为 对象 对于键值 要求太多了 map 无法满足
		2.或者 arr1 = [...map]
	2.map = new Map() map.set(key,value) // map = new Map([[key,value],[key1,value]])
	3.遍历map for(let [key,value] of map){}

数组和set不同

1.比较类似 [...set] 转成一维数组 set添加成员 不能set 多别扭 set.add; let set = new Set ([1,2,3])
2.set 可以去重复数组
3.set.entries() 发现 set 其实就是 键和值 一样的 map,为什么 Set 能去重复 因为 map的key如果重复 后面就被覆盖了 set 底层 map

js高级

数据类型 内存 变量 数据

1.数据类型部分
	1.普通类型 string number boolean undefined null
	2.引用数据类型 Objec Function Array 本质上都属于 对象
2.判断一个变量的类型
	1.tpyeof instanceof ===
3.null 与 undefined 的区别
	1.undefined 表示定义了 但是没有赋值 null 表示定义了 赋值了一个null 对于有的变量 目的时表示对象 只是开始不知道写什么 赋值 null
	2.赋 null 值 的时机
		1.初始化一个准备接受 对象的 变量
		2.准备垃圾回收
4.变量 内存 数据 的对应关系
	1.代码解析后 变量 对应 一个内存地址 内存地址里面 存数据
	2.这个地址对应的内存 存数据
	3.数据可以是 基本类型 和 引用类型 分别在栈内存中 存数据本身 和 对应的 堆内存地址
	4.变量和变量之间 包括实参和形参之间 传递数据 本质是 传递的 内存中 保存的东西 [基本数据 和 地址] 而不是变量本身

函数被调用 和 js关于代码 分号问题

1.函数被调用的几种方式
	1.test() this->window
	2.new test() this->test
	3.obj.test() this->obj
	4.test.call(obj,ar1,ar2) test.apply(obj,[]) this->obj
	5.回调函数 [自己定义了 但自己没有调用 晚些时候 它却自己执行了] [定时器 ajax promise]
	6.iife [immdiately invoked function express] 立即执行函数 直译 立即引用函数表达式
2.关于代码中的 分号 [尤雨溪说]
	1.除了 () [] // + - 为首前加; 其他的不用 // + - 开头基本用不到 所以需要注意的就是 () []

对象原型

0.每一个 函数 都可以认为是 new Function 出来的 所以每个函数 也是对象 都有 __proto__ 和 prototype
1.每一个函数 都有一个 prototype 属性 指向一个 空的 Object 对象 即原型对象
	0.Object 函数除外 因为 Object.prototype.__proto__ 为 null
	1.原型对象有一个  constructor 属性 指向函数对象
	2.fn.__proto__ == Fn.prototype
		1.fn = new Fn() //发生了 this.__proto__ = Fn.prototype
	3.Function 也是 Function new 出来的
2.读属性去查找原型链 写属性不会查找 直接写在对象本身
3.instanceof 的 真正意义是什么
	1. a instanceof b  到底怎么判断的
		1.b.prototype 只要在 a 的原型链上 就返回 true
		2.判断时候 b 走一步 b.prototype a 走无数步 直到 Object.prototype.__proto__ 为 null 形成一个链
		3.a 位置 为对象 b位置为构造函数 a.__proto__........ b.prototype 
		4.判断如下 instanceof
			1.Object instanceof Function true
			2.Object instanceof Object true
			3.Function instanceof Function true
			4.Function instanceof Object true
			5.function Foo(){}; Object instance of Foo false
				1.因为 Foo.prototype 为 {} 走不到 Foo.prototype.__proto__

----4.原型链如下图
image

变量声明提升[预解析]

1.var 声明的变量会提升
	1.var 变量 声明后 会提升到 最前面 并为 undefiend
	2.然后 函数声明 提升 并且赋值为函数本身 如果是函数表达式 和 普通的 变量是没有区别的 只声明 不解析执
2.全局执行上下文
	1.在执行全局代码前 将 window 确定为全局执行上下文
	2.对全局数据进行预解析
		1.var 定义的全局变量 赋值 undefined 并且添加为 window 的属性
		2.函数声明 的全局函数 赋值后 添加为 windwo 的 方法
		3.需要this的地方 赋值为 window
	3.开始执行全局代码
3.函数执行上下文 在调用函数 函数准则运行的瞬间发生 对局部数据进行预处理
	1.形参变量 赋值 实参数据后 添加为 局部执行上下文属性
	2.argumengts  赋值为实参列表 添加为局部执行上下文属性
	3.var 定义的 赋值为 undefiend 添加为局部执行上下文属性
	4.function 声明的方法 赋值该函数后 添加为局部执行上下文方法
	5.this赋值为调用函数的对象

函数作用域

1.只和定义有关 var x = 10; function fn1(){console.log(x)}; function fn2 (fn){var x = 20;fn()}; 调用 fn2(fn1)// 输出 10;
2.var obj = {fn:function(){console.log(fn)}} obj.fn() // 会报错 fn is not defined 如果想访问到 
	1.在对象中 必须加 this console.log(this.fn)

闭包

1.闭包形成的条件
	1.内部函数 访问(读写) 外部函数的 变量 或者参数
	2.闭包产生的时机:定义完毕后就 已经产生了 而不是等到调用 返回的那个函数 ,只要一返回 就产生了
2.闭包的常见写法
	1.返回一个函数 
	2.把函数以 实参传递 给函数 并引用了该函数的变量
3.闭包特点
	1.外部函数一般无法方法 内部变量 但是 闭包后 可以访问
	2.函数执行完毕后 变量销毁 但是 闭包后 变量可以保留在内存
4.闭包的应用
	1.封装模块  (function(w){ function modeulA(){} fuction ModuleB(){} w.$ = {moduleA,moduleB}})(window)
		1.传参的意义在于方便代码的压缩
5.经典闭包 搞人题 代码如下
点击查看代码

function fun(n,o){
    console.log(o)
    return {
        fun:function(m){
            return fun(m,n)
        }
    }
}
var a = fun(0); //undefined
//因为每次返回的都是不同的闭包
a.fun(1) // 0
a.fun(2) // 0
a.fun(3) // 0
//每次都返回了上一次的闭包
fun(0).fun(1).fun(2).fun(3) // undefined 0 1 2

//和第一次差不多 只不过 返回并利用了 第二次 fun(1) 的闭包
var c = fun(0).fun(1); // undefined 0
c.fun(2) //1
c.fun(3) //1

storage

1.loalStorage
	1.loalstorage.setItem("age",JSON.stringify({}))
	2.loalstorage.getItem("age")
	3.loalstorage.removeItem("age")
	4.loalstorage.clear()
2.sessionStorage
	方法同上 sessionStorage.xxxx
3.两者关系
	1.localStorage 需要手动清除
	2.sessionStorage 随着浏览器关闭而消失
	3.如果 getItem("xx") 一个没有的值 返回 null 
		1. 另外 JSON.parse(null)//null

对象创建模式

1.var o = new Object() o.name = "zs" o.fn = function(){console.log("ok")} 缺点:麻烦
	1.用于:不知道初始数据 边走边说
2.var o  {name:"zs",fn(){}} 用于数据开始确定 缺点:麻烦 代码利用率低
3.工厂函数模式 function createPerson(name){o = new Object();o.name=name|| o = {name:name) return o}}
	1.缺点:对象没有一个具体的类型 都是Object
4.自定义函数模式

对象的继承模式

1.原型对象继承 Son.prototype = new Father(); Son.prototype.constructor = Son
2.组合继承 ES5 最完美的 组合继承模式 代码如下
点击查看代码
function F(name,age){
    this.name = name
    this.age = age

}
F.prototype.sayName = function(){
        return this.name
}
function S(name,age,salary){
    F.call(this,name,age)
    this.salary = salary;
}
S.prototype = new F()
S.prototype.constructor = S
S.prototype.work = function(){
    console.log("my name is " + this.sayName() +", I can work,and my salary is " + this.salary)
}
var s = new S("zs",18,3000)
s.work() // my name is zs, I can work,and my salary is 3000
3.Es6 中的 语法糖类 class 代码如下
点击查看代码
    class Person{
        constructor(name){
            this.name = name;
        }
        static [Symbol.hasInstance](para){
            console.log(arguments)

        }
        sayName(){
            console.log("my name is "+ this.name)
        }
    }
    class Wrok extends Person{
        #salary //私有属性 在Es5中 需要用闭包来实现
        constructor(name,work,salary){
            super(name) //一旦重新写 constructor 方法 必须先执行 super()
            super.sayName() //在 任意函数中 可以调用 父类的 方法
            this.work = work;
            this.#salary = salary;
        }
        sayWork(){
            super.sayName() //在 任意函数中 可以调用 父类的 方法
            console.log(`my work is ${this.work},and my salary is ${this.#salary}`)
        }
    }
let s1 = new Wrok("zs","teacher",1800)
s1.sayWork()

关于Worker代码如下:

点击查看代码
//main code
var work = new Worker("./worker.js")
work.onmessage = function(e){
    console.log(e.data + " received from worker")
}
work.postMessage(5)

//about worker.js code
function fibonacci(n){
    return n < 2 ? 1 : fibonacci(n-1) + fibonacci(n-2);
}
onmessage = function(event){
    console.log(event.data +" received form main ");
    postMessage(fibonacci(event.data));
}
4.js的类型转换和比较

image

posted @ 2023-06-20 01:16  闭区间  阅读(18)  评论(0编辑  收藏  举报