├── .github └── workflows │ ├── ci.yml │ └── codeql-analysis.yml ├── .gitignore ├── 1.toFixed()为什么会报错.js ├── ==和===的区别.js ├── Array.prototype.with.js ├── MutationObserver.html ├── Object.assign 给 class 添加 构造参数 └── index.js ├── Promise.all.js ├── Promise.allSettled.js ├── Promise.any.js ├── README.md ├── URL.js ├── URLSearchParams.js ├── __proto__.js ├── after和 before └── index.js ├── array相关 ├── arrayDistinct.js ├── input.json ├── json2CFG.js ├── map和foreach的区别.html ├── some和every.html ├── transJson.js ├── vote.js ├── 不循环生成数组.html ├── 二维数组降维.html ├── 数组去重.html └── 数组的toString().html ├── base64编码解码 └── index.html ├── big.jpg ├── bind 的实现 └── index.js ├── cahce-api ├── cache.html └── js.jpg ├── console.trace ├── cookie.html ├── deepFind.js ├── domContentload和onload.html ├── excel表导入.html ├── fetch的abort.html ├── getHTML.js ├── html的id属性也会生成全局变量.html ├── import-map.html ├── import网络资源 └── index.html ├── isArray.js ├── isInputPending.js ├── isNull.js ├── isPrototypeOf.js ├── iterator.js ├── jquery-1.11.3.js ├── js.jpg ├── leetcode解题 ├── 1.two-sum.js ├── 100.same-tree.js ├── 101.symmetric-tree.js ├── 104.maximum-depth-of-binary-tree.js ├── 107.binary-tree-level-order-traversal-ii.js ├── 108.convert-sorted-array-to-binary-search-tree.js ├── 13.roman-to-integer.js ├── 14.longest-common-prefix.js ├── 1_两个数字的总和.js ├── 20.valid-parentheses.js ├── 21.merge-two-sorted-lists.js ├── 215_找到一个数组中第n 大的数.js ├── 26.remove-duplicates-from-sorted-array.js ├── 28.implement-str-str.js ├── 32_最小子串覆盖.js ├── 35.search-insert-position.js ├── 38.count-and-say.js ├── 53.maximum-subarray.js ├── 58.length-of-last-word.js ├── 66.plus-one.js ├── 7.reverse-integer.js ├── 70.climbing-stairs.js ├── 746_最低成本攀登楼梯.js ├── 83.remove-duplicates-from-sorted-list.js ├── 88.merge-sorted-array.js ├── 9.palindrome-number.js ├── 压缩字符串.js └── 算出棋盘获胜结果.js ├── memoize.js ├── number的最大最小值.js ├── number相关 ├── parsetInt.js └── 十进制指数.html ├── object相关 └── 对象的引用.html ├── package-lock.json ├── package.json ├── parseInt.js ├── passive流畅滚动 └── index.html ├── performance.js ├── private.js ├── qs ├── JSON.parse.js └── JSON.stringify.js ├── react ├── createElement.html ├── react.js └── useState.js ├── react为什么要super(props) └── index.js ├── replaceAll.js ├── serviceWorker获取资源http状态码 ├── index.html ├── index.js └── sw.js ├── setTimeout的第三个参数.js ├── testPostMessage.html ├── this相关 └── this是如何工作的 │ └── index.js ├── trim.js ├── url地址点击返回.html ├── uuid.js ├── valueOf和toString.js ├── webAnimationApi.html ├── ~运算符.js ├── 一些新的原生api ├── Fetch请求.html ├── Notification通知API.html ├── URL.createObjectURL() 生成excel文件.html ├── intersectionObserver.html ├── intersectionObserver实现无限滚动.html ├── postMessage().html ├── requestIdleCallback.html ├── test.jpg └── 浏览器可以替代Jquery的新api.html ├── 三角函数实际应用 ├── 元素散开动画(sin,cos).html └── 跟随鼠标旋转(atan2).html ├── 上传相关 ├── 图片上传.html └── 图片拖拽上传.html ├── 下划线驼峰互转 └── index.js ├── 下载.js ├── 丝滑的回到顶部 └── index.html ├── 中文首字母拼音排序.js ├── 中断 fetch 请求 └── index.html ├── 代理 ├── defineProperty.js ├── reflect.js └── 双向数据绑定1.html ├── 仿淘宝奢侈馆卡片切换特效 ├── index.scss └── index.vue ├── 低级 ├── Date 日期函数.html ├── onunload卸载事件.html ├── setAttribute 属性.html ├── 什么是对象.html ├── 倒计时函数封装.html ├── 兄弟节点.html ├── 删除节点.html ├── 判断当前是什么浏览器.html ├── 复选框全选.html ├── 字符串.html ├── 数组.html ├── 日期小练习.html ├── 替换节点.html ├── 节点综合练习【table表格】.html ├── 计算器.html ├── 返回上一级页面.html ├── 返回值.html └── 选项卡.html ├── 作用域 └── index.js ├── 你还可以输入多少字.html ├── 使用 setPointerCapture 实现拖拽.html ├── 倒计时封装 └── 倒计时封装.html ├── 元素focus后页面不滚动 └── index.html ├── 元素滚动在可视范围.html ├── 函数式编程 ├── 偏函数 │ └── index.js ├── 尾调用 │ └── index.js ├── 柯里化 │ └── index.js ├── 管道-pipe │ └── index.js ├── 组合-compose │ └── index.js ├── 自动柯里化 │ └── index.js └── 高阶函数 │ └── index.js ├── 判断节点之间的位置 └── index.html ├── 利用blob将文本保存为html.html ├── 刷新页面不记住滚动位置.html ├── 前端常用算法 ├── 二叉树节点总和.js ├── 二路归并.js ├── 公共前缀.js ├── 冒泡排序.js ├── 删除1个数字后的最小值.js ├── 判断一个数是否为 2 的整数次幂.js ├── 单循环算法(BO1).js ├── 压缩字符串.js ├── 大数相加.js ├── 字符串反转.js ├── 寻找缺失整数.js ├── 快排.js ├── 找出重复数字.js ├── 找到最大的数.js ├── 插入排序.js ├── 数组中间插入.js ├── 斐波那契数列.js ├── 无序数组最大相邻差.js ├── 最大公约数.js ├── 洗牌算法.js ├── 等差数列求和.js ├── 计数排序.js ├── 连续子数字的最大和.js └── 递归.js ├── 剪贴板.html ├── 剪贴板 └── index.html ├── 加载中.html ├── 原生分享 (navigator.share).html ├── 原生懒加载.html ├── 原生的flat函数 ├── flat.js └── flatMap.js ├── 原生网页分享 └── index.html ├── 原生获取联系人 (navigator.contacts).html ├── 去除空格 └── index.js ├── 去除重复字符串.js ├── 双向绑定 └── index.html ├── 双问号兼容性.html ├── 取色器 └── index.html ├── 变量提升 └── index.js ├── 只能输入整数 └── index.js ├── 周期性执行函数n次 └── index.js ├── 图片放大镜封装 ├── big.jpg ├── imageFDJ.js ├── small.jpg └── 放大镜.html ├── 图片解码.html ├── 圆形进度条封装(canvas版) └── 圆形进度条封装.html ├── 圆形进度条封装(svg版) └── svg.html ├── 填写银行卡4位后自动加空格.html ├── 复制粘贴相关 ├── copy.html ├── 复制功能.html └── 获取剪贴板中的数据.html ├── 字符串去重 └── 1.js ├── 字符串反转.html ├── 字符串超出长度隐藏.html ├── 实现一个instanceof └── index.js ├── 富文本编辑器相关知识点 ├── README.md ├── execCommand.html ├── range.html └── replace.js ├── 将blob 转成 file.html ├── 异步迭代.js ├── 手机震动 └── index.js ├── 拖拽 ├── index.html └── test.json ├── 拖选框.html ├── 捕获Primise 异常.html ├── 控制反转 └── Container.ts ├── 数组的交集和差集.js ├── 文件上传组件封装 ├── LjkUpload.js ├── ljkUpload.css └── ljkUpload.html ├── 文章阅读进度.html ├── 旋转木马轮播封装 ├── .idea │ ├── .name │ ├── encodings.xml │ ├── misc.xml │ ├── modules.xml │ ├── workspace.xml │ └── 旋转木马轮播封装.iml ├── 11.css ├── images │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ └── 6.jpg ├── lunbo.html ├── lunbo.js └── test.js ├── 是否为URL.js ├── 标签函数.js ├── 标签函数String.raw.js ├── 格式化文件大小 └── index.js ├── 检测是否支持css属性.js ├── 楼层定位.html ├── 模仿封装 ├── js旋转(模仿).html ├── js旋转.html ├── 仿jQuery[slideDown()]方法封装.html └── 模拟jquery AJAX方法封装.html ├── 模板.html ├── 模板解析 ├── parse.js └── render.js ├── 横竖屏检测 └── index.html ├── 正则去掉 html 标签字符串里的所有属性.html ├── 正则和split实现完美的逗号分隔字符串.js ├── 正则捕获组 └── index.js ├── 汉字按拼音首字母分组排序 └── index.js ├── 浅拷贝与深拷贝 ├── deepClone.js └── shallowCopy.js ├── 浏览器原生深拷贝.js ├── 浏览器合成事件getCoalescedEvents └── index.html ├── 浏览器新的获取本地文件API.html ├── 深拷贝.js ├── 深色模式判断.js ├── 游戏手柄 └── index.html ├── 滚动加载 └── index.html ├── 环境光 └── index.js ├── 生命游戏 └── index.html ├── 生成随机字母 └── index.js ├── 监听dom尺寸变化 └── index.html ├── 移动端双指缩放图片.html ├── 练习 ├── bind.js ├── curry.js ├── debounce.js ├── throttle.js ├── 冒泡排序.js ├── 布局.html ├── 快排.js └── 简易模板引擎.js ├── 经纬度转换 └── index.js ├── 继承 ├── 玩玩call和apply继承.html ├── 继承.html └── 继承几种实现方式.html ├── 编程练习 ├── 0.5像素边框.html ├── Koa洋葱模型.js ├── axios拦截器.js ├── bind.js ├── curry.js ├── debounce.js ├── extend.js ├── fetch的abort.html ├── jsonp.html ├── jsonp.server.js ├── orderBy.js ├── print.js ├── reduce.js ├── reduce实现map.js ├── throttle.js ├── 冒泡排序.js ├── 千分位转数字.js ├── 单向链表.js ├── 双向绑定.html ├── 发布订阅模式.js ├── 实现一个new.js ├── 快排.js ├── 拍平数组.js ├── 数字转千分位.js ├── 数据响应式.js ├── 数组去重.js ├── 深拷贝.js ├── 简化promise.js ├── 简易模板引擎.js ├── 累加函数.js └── 观察者模式.js ├── 编译原理 └── 抽象语法树 │ └── index.js ├── 自定义CSS 属性(chorme78 新增) └── index.html ├── 自适应瀑布流.html ├── 获取所有路径组合 └── index.js ├── 虚拟dom.html ├── 视频截图.html ├── 视频画中画 └── index.html ├── 设计模式 ├── 单例模式 │ └── index.html ├── 职责链模式 │ └── index.js └── 订阅发布模式 │ └── index.js ├── 请求超时 ├── index.html └── index.js ├── 赋值运算符.js ├── 路由改变回到顶部.tsx ├── 转换 react 路由.js ├── 轮播封装 └── 轮播封装.html ├── 轮播封装优化版 ├── LJKBanner.css ├── LJKBanner.html ├── LJKBanner.js └── images │ ├── banner1.jpg │ ├── banner2.jpg │ ├── banner3.jpg │ ├── banner4.jpg │ ├── banner5.jpg │ ├── left-arrow.png │ └── right-arrow.png ├── 输入sb └── index.js ├── 迷你redux ├── compose.js └── store.js ├── 链式调用 └── index.js ├── 闭包 ├── 闭包.html ├── 闭包2.html └── 闭包3.html ├── 随机汉字.html ├── 随机颜色.html ├── 震动.html ├── 验证码.html ├── 高级 ├── call继承.html ├── try-catch语句.html ├── 函数块级.html ├── 函数,switch ,循环.html ├── 原始表达式.html ├── 在元素创建之前绑定事件.html ├── 对象.html ├── 类型检测.html ├── 运算符.html └── 隐式转换.html └── 鼠标拖拽效果.html /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | node-version: [14.x] 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Use Node.js ${{ matrix.node-version }} 15 | uses: actions/setup-node@v1 16 | with: 17 | node-version: ${{ matrix.node-version }} 18 | 19 | - name: install dependencies 20 | run: | 21 | npm install -g j-bookmark 22 | 23 | - name: build bookmark 24 | run: | 25 | bookmark -p /javascript-demos 26 | env: 27 | CI: true 28 | 29 | - name: Deploy 30 | uses: peaceiris/actions-gh-pages@v3 31 | with: 32 | github_token: ${{ secrets.GITHUB_TOKEN }} 33 | publish_dir: ./ 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | .history 5 | node_modules 6 | .vscode 7 | # Folder config file 8 | Desktop.ini 9 | .site 10 | .storybook 11 | .idea 12 | 13 | # Recycle Bin used on file shares 14 | $RECYCLE.BIN/ 15 | 16 | # Windows Installer files 17 | *.cab 18 | *.msi 19 | *.msm 20 | *.msp 21 | 22 | # Windows shortcuts 23 | *.lnk 24 | 25 | # ========================= 26 | # Operating System Files 27 | # ========================= 28 | 29 | # OSX 30 | # ========================= 31 | 32 | .DS_Store 33 | .AppleDouble 34 | .LSOverride 35 | 36 | # Thumbnails 37 | ._* 38 | 39 | # Files that might appear in the root of a volume 40 | .DocumentRevisions-V100 41 | .fseventsd 42 | .Spotlight-V100 43 | .TemporaryItems 44 | .Trashes 45 | .VolumeIcon.icns 46 | 47 | # Directories potentially created on remote AFP share 48 | .AppleDB 49 | .AppleDesktop 50 | Network Trash Folder 51 | Temporary Items 52 | .apdisk 53 | -------------------------------------------------------------------------------- /1.toFixed()为什么会报错.js: -------------------------------------------------------------------------------- 1 | console.log(1.toFixed(2)); 2 | 3 | // SyntaxError: Invalid or unexpected token 4 | 5 | // 上面之所以会报错 是因为 1 => 1.0 => 1. 在js里面都是可以的 6 | 7 | console.log((1).toFixed(2)); // 1.00 8 | console.log((1).toFixed(2)); // 1.00 9 | console.log((1.0).toFixed(2)); // 1.00 10 | -------------------------------------------------------------------------------- /==和===的区别.js: -------------------------------------------------------------------------------- 1 | // 往往一问到 == 和 === 的区别,就会说 == 不比较类型 === 会比较类型 2 | 3 | console.log( 1 == "1") 4 | console.log( 1 === "1" ) 5 | 6 | // 看了你不知道的javascript才知道 原来唯一的区别是 === 不会做隐式转换 7 | 8 | // 1 == "1" 内部会做 所以相等, 我曹,好有道理 9 | 10 | // 转换规则:会把字符串转成数字 11 | 12 | // 1 == "1" =》 1 == Number("1") 13 | 14 | 15 | console.log( true == "1") 16 | 17 | // 转换规则 18 | 19 | // true == "1" => Number(true) == "1" => 1 == "1" true 20 | 21 | console.log( true == "13") 22 | 23 | // 转换规则 24 | 25 | // true == "13" => Number(true) == "13" => 1 == "13" false 26 | -------------------------------------------------------------------------------- /Array.prototype.with.js: -------------------------------------------------------------------------------- 1 | const ages = [10, 15, 20, 25]; 2 | 3 | const newAges = ages.with(1, 16); 4 | console.log(newAges); // [10, 16, 20, 25] 5 | console.log(ages); 6 | -------------------------------------------------------------------------------- /MutationObserver.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |
10 | 11 | 28 | 29 | -------------------------------------------------------------------------------- /Object.assign 给 class 添加 构造参数/index.js: -------------------------------------------------------------------------------- 1 | class A { 2 | constructor(args) { 3 | this.name = args.name 4 | this.age = args.age 5 | this.sex = args.sex 6 | } 7 | say() { 8 | console.log(this.name); 9 | console.log(this.age); 10 | console.log(this.sex); 11 | } 12 | } 13 | 14 | const a = new A({ 15 | name: "ljk", 16 | age: 18, 17 | sex: '男' 18 | }) 19 | 20 | a.say() 21 | 22 | 23 | class B { 24 | constructor(args) { 25 | Object.assign(this, args) 26 | } 27 | say() { 28 | console.log(this.name); 29 | console.log(this.age); 30 | console.log(this.sex); 31 | } 32 | } 33 | 34 | const b = new B({ 35 | name: "ljk", 36 | age: 18, 37 | sex: '男' 38 | }) 39 | 40 | b.say() 41 | -------------------------------------------------------------------------------- /Promise.all.js: -------------------------------------------------------------------------------- 1 | const sleep = (duration) => 2 | new Promise((resolve) => setTimeout(() => resolve(duration), duration)); 3 | 4 | async function all(list) { 5 | return new Promise((res, rej) => { 6 | let count = 0; 7 | const result = []; 8 | 9 | list.forEach((item) => { 10 | Promise.resolve(item) 11 | .then((data) => { 12 | result.push(data); 13 | count++; 14 | 15 | if (count === list.length) { 16 | res(result); 17 | } 18 | }) 19 | .catch(rej); 20 | }); 21 | }); 22 | } 23 | 24 | all([sleep(1000), sleep(2000), sleep(3000)]).then((res) => { 25 | console.log(res); 26 | }); 27 | -------------------------------------------------------------------------------- /Promise.allSettled.js: -------------------------------------------------------------------------------- 1 | const promise1 = Promise.resolve(100); 2 | const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'info')); 3 | const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'name')) 4 | 5 | Promise.allSettled([promise1, promise2, promise3]). 6 | then((results) => console.log(results)); 7 | -------------------------------------------------------------------------------- /Promise.any.js: -------------------------------------------------------------------------------- 1 | const promise1 = Promise.resolve(100); 2 | const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'info')); 3 | const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'name')) 4 | 5 | Promise.allSettled([promise1, promise2, promise3]). 6 | then((results) => console.log(results)); 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # javascript-demos 2 | 3 | ![Node CI](https://github.com/lijinke666/javascript-demos/workflows/Node%20CI/badge.svg) 4 | 5 | 日常积累的知识点和代码片段 6 | -------------------------------------------------------------------------------- /URL.js: -------------------------------------------------------------------------------- 1 | const url = new URL('https://www.lijinke.cn?s=1') 2 | const relativeUrl = new URL('/test', 'https://www.lijinke.cn') 3 | 4 | console.log(url.host) // www.lijinke.cn 5 | console.log(url) 6 | 7 | console.log(relativeUrl.href) // www.lijinke.cn 8 | -------------------------------------------------------------------------------- /URLSearchParams.js: -------------------------------------------------------------------------------- 1 | 2 | const str = 'name=ljk&age=18' 3 | 4 | const url = new URLSearchParams(str) 5 | 6 | console.log(url.get("name")); // ljk 7 | console.log(url.has("name")); // true 8 | console.log(url.delete('age')) 9 | console.log(url.append('text', 123)) 10 | console.log(url.set('text', 22222)) 11 | 12 | console.log(url.toString()) // name=ljk&text=22222 13 | -------------------------------------------------------------------------------- /__proto__.js: -------------------------------------------------------------------------------- 1 | 1..__proto__ === Number.prototype; // true 2 | 1'.__proto__ === String.prototype; // true 3 | true.__proto__ === Boolean.prototype; // true 4 | -------------------------------------------------------------------------------- /after和 before/index.js: -------------------------------------------------------------------------------- 1 | Function.prototype.before = function(fn) { 2 | const self = this 3 | return function(...attr) { 4 | fn.apply(this, attr) 5 | return self.apply(this, attr) 6 | } 7 | } 8 | 9 | Function.prototype.after = function(fn) { 10 | const self = this 11 | return function(...attr) { 12 | const result = self.apply(this, attr) 13 | fn.apply(this, attr) 14 | return result 15 | } 16 | } 17 | 18 | console.log.before(()=>{ 19 | console.log('before....'); 20 | })('log....') 21 | 22 | console.log.after(()=>{ 23 | console.log('after....'); 24 | })('log...') 25 | 26 | const fn = () => { 27 | console.log('start...'); 28 | } 29 | 30 | const f = fn.after(()=>{ 31 | console.log('after'); 32 | }) 33 | 34 | f() 35 | -------------------------------------------------------------------------------- /array相关/arrayDistinct.js: -------------------------------------------------------------------------------- 1 | function arrayDistinct(targetArray) { 2 | if(!Array.isArray(targetArray)){ 3 | return targetArray 4 | } 5 | if(targetArray.some((item)=> Object.is(typeof item,"object"))){ 6 | return targetArray 7 | .map((item) => JSON.stringify(item)) 8 | .filter((item, idx, arry) => idx === arry.findIndex( (current)=> current === item)) 9 | .map((item) => JSON.parse(item)) 10 | } 11 | return [...new Set(targetArray)] 12 | } 13 | 14 | const testDistinctArray = { 15 | object:{ 16 | init: [ 17 | {id:1,name:"react"}, 18 | {id:1,name:"react"}, 19 | ['node'], 20 | ['node'] 21 | ], 22 | result:[ 23 | {id:1,name:"react"}, 24 | ['node'], 25 | ] 26 | }, 27 | stringOrNumber:{ 28 | init:["1","1",2,2], 29 | result:["1",2] 30 | } 31 | } 32 | 33 | 34 | console.log(arrayDistinct(testDistinctArray.object.init)); 35 | -------------------------------------------------------------------------------- /array相关/map和foreach的区别.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | map和foreach的区别 6 | 7 | 8 | 9 | 10 | 21 | -------------------------------------------------------------------------------- /array相关/some和every.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | some 和 every 9 | 10 | 11 | 12 | 13 | 14 | 44 | 45 | -------------------------------------------------------------------------------- /array相关/transJson.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs') 3 | const path = require('path') 4 | const input = 5 | JSON.parse(fs.readFileSync(path.resolve(__dirname,"./input.json")).toString()) 6 | /** 7 | * @name transJson 8 | * @param {Array} json 需要转换的数据 9 | */ 10 | const transJson = json => { 11 | const result = json.reduce( 12 | ( 13 | arr, 14 | { 15 | qid, 16 | enable, 17 | question, 18 | totalPrizePool, 19 | startTime, 20 | endTime, 21 | showTime, 22 | answer, 23 | ...answers 24 | } 25 | ) => { 26 | const _answers = Object.keys(answers) 27 | .filter(v => v.toLocaleLowerCase().startsWith("answer")) 28 | .map(v => { 29 | const value = v.replace(/^(answer)(\w)/i,(a,b,c)=> `${b}|${c}`) 30 | const [des,option] = value.split('|') 31 | return {option,des} 32 | }); 33 | 34 | const v = { 35 | qid, 36 | enable, 37 | question, 38 | totalPrizePool, 39 | startTime:new Date(startTime), 40 | endTime: new Date(endTime), 41 | showTime: new Date(showTime), 42 | answers: _answers, 43 | answer 44 | }; 45 | arr.push(v); 46 | return arr; 47 | }, 48 | [] 49 | ); 50 | return JSON.stringify(result, undefined, 2) 51 | }; 52 | 53 | console.log(transJson(input)); 54 | -------------------------------------------------------------------------------- /array相关/不循环生成数组.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |

不循环生成n个数组 下标与值相等

13 | 14 | 31 | 32 | -------------------------------------------------------------------------------- /array相关/二维数组降维.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 58 | -------------------------------------------------------------------------------- /array相关/数组去重.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 数组去重 6 | 7 | 8 |

思路:

9 |

1.创建一个新的数组存放结果

10 |

2.创建一个空对象

11 |

3.for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。

12 | 说明:至于如何对比,就是每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复。 13 | 14 | 36 | -------------------------------------------------------------------------------- /array相关/数组的toString().html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /base64编码解码/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/big.jpg -------------------------------------------------------------------------------- /bind 的实现/index.js: -------------------------------------------------------------------------------- 1 | const max = (arr) => Math.max(...arr) 2 | //bind 返回一个 函数 用于 改变上下文 3 | const max_bind = max.bind(this,[1,2,3]) 4 | console.log(max_bind()); 5 | 6 | 7 | //第二种 8 | const obj = { 9 | name:"李金珂", 10 | sayName(text = "我是"){ 11 | console.log(`${text}:${this.name}`) 12 | } 13 | } 14 | 15 | obj.sayName() //我是:李金珂 16 | 17 | obj.sayName.bind({name:'盲僧'})('我不是') //我不是:盲僧 改变了 this 指针 18 | 19 | 20 | 21 | //通过 apply 改变上下文 22 | Function.prototype._bind = function(ctx,...args){ 23 | return (...applyArgs)=> this.apply(ctx,[...args,...applyArgs]) 24 | } 25 | 26 | obj.sayName._bind({name:"石头人"})('test') //test:石头人 -------------------------------------------------------------------------------- /cahce-api/cache.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cache-api 8 | 9 | 10 |

图片被缓存

11 | 12 | 13 | 44 | -------------------------------------------------------------------------------- /cahce-api/js.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/cahce-api/js.jpg -------------------------------------------------------------------------------- /console.trace: -------------------------------------------------------------------------------- 1 | function d(a) { 2 | console.trace(); 3 | return a; 4 | } 5 | function b(a) { 6 | return c(a); 7 | } 8 | function c(a) { 9 | return d(a); 10 | } 11 | let a = b('123'); 12 | -------------------------------------------------------------------------------- /deepFind.js: -------------------------------------------------------------------------------- 1 | const deepFind = () => { 2 | return 3 | .filter(({ list }) => { 4 | return list.length >= 1 5 | && list.some(({ data }) => data.some(({ count }) => count >= 1)) 6 | }) 7 | } 8 | 9 | deepFind([{ 10 | list:[] 11 | },{ 12 | list:[{ 13 | data: [] 14 | }] 15 | },{ 16 | list:[{ 17 | data: [{ 18 | count: 1 19 | }] 20 | }] 21 | }]) 22 | -------------------------------------------------------------------------------- /domContentload和onload.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |
dom节点
10 | 11 | 22 | 23 | -------------------------------------------------------------------------------- /excel表导入.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | excel 6 | 7 | 8 | 9 | 22 | -------------------------------------------------------------------------------- /fetch的abort.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 29 | 30 | -------------------------------------------------------------------------------- /getHTML.js: -------------------------------------------------------------------------------- 1 | const div = document.createElement('div') 2 | div.setHTMLUnsafe('hi, ljk') 3 | div.getHTML() 4 | -------------------------------------------------------------------------------- /html的id属性也会生成全局变量.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |
10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /import-map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 10 | 11 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /import网络资源/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 20 | -------------------------------------------------------------------------------- /isArray.js: -------------------------------------------------------------------------------- 1 | const testArray = [1,2,3] 2 | console.log(typeof testArray); //object :( 3 | 4 | //利用 object 的 toString 方法 5 | 6 | console.log(testArray.toString()); 7 | console.log(Object.prototype.toString.call(testArray)); //[object Array] 8 | 9 | const isArray = (arr)=> Object.prototype.toString.call(arr) === "[object Array]" 10 | 11 | console.log(isArray(testArray)); //true 12 | console.log(isArray({testArray})); //false -------------------------------------------------------------------------------- /isInputPending.js: -------------------------------------------------------------------------------- 1 | // chorme 提供的 调度器 Api, 适用于 Fiber 2 | 3 | console.log(navigator.scheduling.isInputPending()) 4 | 5 | // 连续事件也包含在内 : mousemove 6 | console.log(navigator.scheduling.isInputPending({includeContinuous: true})) 7 | 8 | // 指定某些事件 9 | console.log(navigator.scheduling.isInputPending(['mousemove','pointermove'])) 10 | 11 | 12 | // https://web.dev/isinputpending/ 13 | const DEADLINE = performance.now() + QUANTUM; 14 | while (workQueue.length > 0) { 15 | if (navigator.scheduling.isInputPending() || performance.now() >= DEADLINE) { 16 | // Yield if we have to handle an input event, or we're out of time. 17 | setTimeout(processWorkQueue); 18 | return; 19 | } 20 | let job = workQueue.shift(); 21 | job.execute(); 22 | } 23 | -------------------------------------------------------------------------------- /isNull.js: -------------------------------------------------------------------------------- 1 | export const isNull = (value) => !value && typeof value === 'object' 2 | -------------------------------------------------------------------------------- /isPrototypeOf.js: -------------------------------------------------------------------------------- 1 | var a = {} 2 | 3 | var b = Object.create(a) 4 | 5 | // es6 语法 6 | // Object.setPrototypeOf(a, b) 7 | 8 | console.log(a.isPrototypeOf(b)) // true 9 | -------------------------------------------------------------------------------- /iterator.js: -------------------------------------------------------------------------------- 1 | var arr = ['w', 'y', 'k', 'o', 'p']; 2 | var eArr = arr[Symbol.iterator](); 3 | console.log(eArr.next().value); // w 4 | console.log(eArr.next().value); // y 5 | console.log(eArr.next().value); // k 6 | console.log(eArr.next().value); // o 7 | console.log(eArr.next().value); 8 | 9 | 10 | for (let letter of eArr) { 11 | console.log(letter.next().value); 12 | } -------------------------------------------------------------------------------- /js.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/js.jpg -------------------------------------------------------------------------------- /leetcode解题/1.two-sum.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=1 lang=javascript 3 | * 4 | * [1] Two Sum 5 | */ 6 | /** 7 | * @param {number[]} nums 8 | * @param {number} target 9 | * @return {number[]} 10 | */ 11 | var twoSum = function(nums, target) { 12 | let result = [] 13 | for (let i = 0; i < nums.length; i++) { 14 | for (let j = i + 1; j < nums.length; j++) { 15 | if (nums[i] + nums[j] === target) { 16 | result = [i, j] 17 | break 18 | } 19 | } 20 | } 21 | return result 22 | } 23 | -------------------------------------------------------------------------------- /leetcode解题/104.maximum-depth-of-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=104 lang=javascript 3 | * 4 | * [104] Maximum Depth of Binary Tree 5 | * 6 | * https://leetcode.com/problems/maximum-depth-of-binary-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (62.05%) 10 | * Likes: 1655 11 | * Dislikes: 61 12 | * Total Accepted: 615K 13 | * Total Submissions: 981.1K 14 | * Testcase Example: '[3,9,20,null,null,15,7]' 15 | * 16 | * Given a binary tree, find its maximum depth. 17 | * 18 | * The maximum depth is the number of nodes along the longest path from the 19 | * root node down to the farthest leaf node. 20 | * 21 | * Note: A leaf is a node with no children. 22 | * 23 | * Example: 24 | * 25 | * Given binary tree [3,9,20,null,null,15,7], 26 | * 27 | * 28 | * ⁠ 3 29 | * ⁠ / \ 30 | * ⁠ 9 20 31 | * ⁠ / \ 32 | * ⁠ 15 7 33 | * 34 | * return its depth = 3. 35 | * 36 | */ 37 | 38 | // @lc code=start 39 | /** 40 | * Definition for a binary tree node. 41 | * function TreeNode(val) { 42 | * this.val = val; 43 | * this.left = this.right = null; 44 | * } 45 | */ 46 | /** 47 | * @param {TreeNode} root 48 | * @return {number} 49 | * @description 二叉树的最大深度 递归遍历 左右两个节点 50 | * 发现有节点 就 + 1 51 | * 最后比较左右两个节点数即可 52 | */ 53 | var maxDepth = function(root) { 54 | if (!root) { 55 | return 0 56 | } 57 | const left = maxDepth(root.left) 58 | const right = maxDepth(root.right) 59 | return Math.max(left, right) + 1 60 | } 61 | // @lc code=end 62 | -------------------------------------------------------------------------------- /leetcode解题/1_两个数字的总和.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 给定一个整数数组,返回两个数字的索引,使它们加起来成为一个特定的目标。 3 | * 您可能会认为每个输入都只有一个解决方案,而且您可能不会使用相同的元素两次。 4 | * @param {number} nums 两个数字的总和 5 | * @param {number[]} target 目标数组 6 | */ 7 | const twoSum = (nums, target) =>{ 8 | let index1 = 0 9 | let index2 = 0 10 | 11 | for(let [i,v] of target.entries()){ 12 | for(let [k,j] of target.entries()){ 13 | if(v + j === nums){ 14 | index1 = i 15 | index2 = k 16 | break 17 | } 18 | } 19 | } 20 | if(index1 == 0 && index2 ==0){ 21 | throw new Error('未找到解决') 22 | } 23 | return [index1,index2] 24 | }; 25 | 26 | console.log(twoSum(9,[2,7,11,15])); 27 | console.log(twoSum(3,[4,5,1,2])); 28 | console.log(twoSum(10,[2,3,8,7])); -------------------------------------------------------------------------------- /leetcode解题/215_找到一个数组中第n 大的数.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} k 4 | * @return {number} 5 | * 找到 一个 数组中 第 n 大 的 数 6 | * 先倒序排序 取 第 n - 1 下标 7 | */ 8 | const findKthLargest = (nums, k) => { 9 | const _k = Math.max(Math.min(nums.length, k), 1) 10 | return nums.sort((n1,n2)=> n2 - n1)[_k - 1] 11 | }; 12 | 13 | findKthLargest([3,2,1,5,6,4], 2) // 5 14 | -------------------------------------------------------------------------------- /leetcode解题/32_最小子串覆盖.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {String} source 源字符串 4 | * @param {String} target 目标字符串 5 | * 给出source = "ADOBECODEBANC",target = "ABC" 满足要求的解 "BANC" 6 | * TODO 7 | */ 8 | const minWindow = function (source, target) { 9 | let index1 = [] 10 | for (let str2 of source) { 11 | for (let str1 of target) { 12 | 13 | if (str2 === str1) { 14 | index1.push(source.indexOf(str1)) 15 | } 16 | } 17 | } 18 | 19 | 20 | 21 | return index1 22 | } 23 | 24 | 25 | const source = "ADOBECODEBANC" 26 | const target = "ABC" 27 | const result = minWindow(source, target) 28 | 29 | console.log(result); -------------------------------------------------------------------------------- /leetcode解题/38.count-and-say.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=38 lang=javascript 3 | * 4 | * [38] Count and Say 5 | * 6 | * https://leetcode.com/problems/count-and-say/description/ 7 | * 8 | * algorithms 9 | * Easy (41.72%) 10 | * Likes: 906 11 | * Dislikes: 7107 12 | * Total Accepted: 318K 13 | * Total Submissions: 759.8K 14 | * Testcase Example: '1' 15 | * 16 | * The count-and-say sequence is the sequence of integers with the first five 17 | * terms as following: 18 | * 19 | * 20 | * 1. 1 21 | * 2. 11 22 | * 3. 21 23 | * 4. 1211 24 | * 5. 111221 25 | * 26 | * 27 | * 1 is read off as "one 1" or 11. 28 | * 11 is read off as "two 1s" or 21. 29 | * 21 is read off as "one 2, then one 1" or 1211. 30 | * 31 | * Given an integer n where 1 ≤ n ≤ 30, generate the n^th term of the 32 | * count-and-say sequence. 33 | * 34 | * Note: Each term of the sequence of integers will be represented as a 35 | * string. 36 | * 37 | * 38 | * 39 | * Example 1: 40 | * 41 | * 42 | * Input: 1 43 | * Output: "1" 44 | * 45 | * 46 | * Example 2: 47 | * 48 | * 49 | * Input: 4 50 | * Output: "1211" 51 | * 52 | */ 53 | 54 | // @lc code=start 55 | /** 56 | * @param {number} n 57 | * @return {string} 58 | */ 59 | var countAndSay = function(n) { 60 | 61 | }; 62 | // @lc code=end 63 | 64 | -------------------------------------------------------------------------------- /leetcode解题/53.maximum-subarray.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=53 lang=javascript 3 | * 4 | * [53] Maximum Subarray 5 | * 6 | * https://leetcode.com/problems/maximum-subarray/description/ 7 | * 8 | * algorithms 9 | * Easy (44.55%) 10 | * Likes: 5176 11 | * Dislikes: 201 12 | * Total Accepted: 641.5K 13 | * Total Submissions: 1.4M 14 | * Testcase Example: '[-2,1,-3,4,-1,2,1,-5,4]' 15 | * 16 | * Given an integer array nums, find the contiguous subarray (containing at 17 | * least one number) which has the largest sum and return its sum. 18 | * 19 | * Example: 20 | * 21 | * 22 | * Input: [-2,1,-3,4,-1,2,1,-5,4], 23 | * Output: 6 24 | * Explanation: [4,-1,2,1] has the largest sum = 6. 25 | * 26 | * 27 | * Follow up: 28 | * 29 | * If you have figured out the O(n) solution, try coding another solution using 30 | * the divide and conquer approach, which is more subtle. 31 | * 32 | */ 33 | 34 | // @lc code=start 35 | /** 36 | * @param {number[]} nums 37 | * @return {number} 38 | */ 39 | // 卡在 第 200 关 内存不够 40 | var maxSubArray = function(nums) { 41 | const sum = (nums) => nums.reduce((num, v) => (num += v), 0) 42 | const group = [] 43 | for (let i = 0; i < nums.length; i++) { 44 | if (nums[i] >= 0) { 45 | for (let j = i; j < nums.length; j++) { 46 | if (nums[j] >= 0) { 47 | group.push(sum(nums.slice(i, j + 1))) 48 | } 49 | } 50 | } 51 | } 52 | if (!group.length) { 53 | return Math.max(...nums) 54 | } 55 | return Math.max(...group) 56 | } 57 | 58 | // @lc code=end 59 | -------------------------------------------------------------------------------- /leetcode解题/58.length-of-last-word.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=58 lang=javascript 3 | * 4 | * [58] Length of Last Word 5 | * 6 | * https://leetcode.com/problems/length-of-last-word/description/ 7 | * 8 | * algorithms 9 | * Easy (32.29%) 10 | * Likes: 452 11 | * Dislikes: 1867 12 | * Total Accepted: 303.2K 13 | * Total Submissions: 938K 14 | * Testcase Example: '"Hello World"' 15 | * 16 | * Given a string s consists of upper/lower-case alphabets and empty space 17 | * characters ' ', return the length of last word in the string. 18 | * 19 | * If the last word does not exist, return 0. 20 | * 21 | * Note: A word is defined as a character sequence consists of non-space 22 | * characters only. 23 | * 24 | * Example: 25 | * 26 | * 27 | * Input: "Hello World" 28 | * Output: 5 29 | * 30 | * 31 | * 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | /** 37 | * @param {string} s 38 | * @return {number} 39 | */ 40 | var lengthOfLastWord = function(s) { 41 | if (!s.trim()) { 42 | return 0 43 | } 44 | const word = s.split(' ') 45 | const reverseWord = [...word].reverse() 46 | 47 | const lastIndex = 48 | word.length - reverseWord.findIndex((str) => !!str.trim()) - 1 49 | return word[lastIndex].length 50 | } 51 | // @lc code=end 52 | -------------------------------------------------------------------------------- /leetcode解题/7.reverse-integer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=7 lang=javascript 3 | * 4 | * [7] Reverse Integer 5 | * 6 | * https://leetcode.com/problems/reverse-integer/description/ 7 | * 8 | * algorithms 9 | * Easy (25.49%) 10 | * Likes: 2439 11 | * Dislikes: 3788 12 | * Total Accepted: 802K 13 | * Total Submissions: 3.1M 14 | * Testcase Example: '123' 15 | * 16 | * Given a 32-bit signed integer, reverse digits of an integer. 17 | * 18 | * Example 1: 19 | * 20 | * 21 | * Input: 123 22 | * Output: 321 23 | * 24 | * 25 | * Example 2: 26 | * 27 | * 28 | * Input: -123 29 | * Output: -321 30 | * 31 | * 32 | * Example 3: 33 | * 34 | * 35 | * Input: 120 36 | * Output: 21 37 | * 38 | * 39 | * Note: 40 | * Assume we are dealing with an environment which could only store integers 41 | * within the 32-bit signed integer range: [−2^31,  2^31 − 1]. For the purpose 42 | * of this problem, assume that your function returns 0 when the reversed 43 | * integer overflows. 44 | * 45 | */ 46 | /** 47 | * @param {number} x 48 | * @return {number} 49 | */ 50 | var reverse = function(x) { 51 | if (x == 0) return 0 52 | const [prefix, n] = String(x) 53 | .replace(/(-?)(\d*)/, (_, b, c) => [b, c]) 54 | .split(',') 55 | 56 | const num = n 57 | .split('') 58 | .reverse() 59 | .join('') 60 | 61 | const result = Number(prefix + num) 62 | if (result < Math.pow(-2, 31) || result > Math.pow(2, 31) - 1) return 0 63 | return result 64 | } 65 | 66 | console.log(reverse(1534236469)) 67 | console.log(reverse(120)) 68 | -------------------------------------------------------------------------------- /leetcode解题/70.climbing-stairs.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=70 lang=javascript 3 | * 4 | * [70] Climbing Stairs 5 | * 6 | * https://leetcode.com/problems/climbing-stairs/description/ 7 | * 8 | * algorithms 9 | * Easy (45.06%) 10 | * Likes: 2781 11 | * Dislikes: 98 12 | * Total Accepted: 493.3K 13 | * Total Submissions: 1.1M 14 | * Testcase Example: '2' 15 | * 16 | * You are climbing a stair case. It takes n steps to reach to the top. 17 | * 18 | * Each time you can either climb 1 or 2 steps. In how many distinct ways can 19 | * you climb to the top? 20 | * 21 | * Note: Given n will be a positive integer. 22 | * 23 | * Example 1: 24 | * 25 | * 26 | * Input: 2 27 | * Output: 2 28 | * Explanation: There are two ways to climb to the top. 29 | * 1. 1 step + 1 step 30 | * 2. 2 steps 31 | * 32 | * 33 | * Example 2: 34 | * 35 | * 36 | * Input: 3 37 | * Output: 3 38 | * Explanation: There are three ways to climb to the top. 39 | * 1. 1 step + 1 step + 1 step 40 | * 2. 1 step + 2 steps 41 | * 3. 2 steps + 1 step 42 | * 43 | * 44 | */ 45 | 46 | // @lc code=start 47 | /** 48 | * @param {number} n 49 | * @return {number} 50 | * @description 斐波那契数列 51 | * n = 0 1种可能 (1 步) 52 | * n = 1 1种可能 [1] (1 步) 53 | * n = 2 两种可能 [1,2] 54 | * n = 3 三种可能 [1,1,1] [1,2] [2,1] 55 | * n = n - 1 + n - 2 56 | */ 57 | var climbStairs = function(n) { 58 | // 由于 前两步(0,1)都只需要一步 所以直接从 第三步 也就是 (2) 开始 59 | const step = [1, 1] 60 | for (let i = 2; i <= n; i++) { 61 | step[i] = step[i - 1] + step[i - 2] 62 | } 63 | console.log(step) 64 | return step[n] 65 | } 66 | 67 | // @lc code=end 68 | -------------------------------------------------------------------------------- /leetcode解题/746_最低成本攀登楼梯.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 注意: 3 | * cost将有一个在该范围内的长度[2, 1000]。 4 | * 每个cost[i]将会是范围内的一个整数[0, 999]。 5 | * 第一步可以从 下标为0 或者 1 开始 6 | * @param {number []} cost 成本 7 | * @return {number} 8 | */ 9 | const minCostClimbingStairs = (cost) =>{ 10 | if(!Array.isArray(cost) || cost.length <2 || cost.length > 1000){ 11 | throw new Error('cost between [2,1000]') 12 | } 13 | if( cost.some( v => !Object.is(typeof (v),'number') || v <0 || v>999 ) ){ 14 | throw new Error('const[i] should between [0,999] and should be a number') 15 | } 16 | 17 | let num1 = 0 18 | let num2 = 0 19 | 20 | for(let i = cost.length-1; i>=0; --i){ 21 | let num0 = cost[i] + Math.min(num1,num2) 22 | num2 = num1 23 | num1 = num0 24 | } 25 | return Math.min(num1,num2) 26 | } 27 | 28 | console.log(minCostClimbingStairs([10,15,20])) //15 29 | console.log(minCostClimbingStairs([1, 100, 1, 1, 1, 100, 1, 1, 100, 1])) //6 -------------------------------------------------------------------------------- /leetcode解题/83.remove-duplicates-from-sorted-list.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=83 lang=javascript 3 | * 4 | * [83] Remove Duplicates from Sorted List 5 | * 6 | * https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/ 7 | * 8 | * algorithms 9 | * Easy (43.36%) 10 | * Likes: 954 11 | * Dislikes: 87 12 | * Total Accepted: 374.1K 13 | * Total Submissions: 858.4K 14 | * Testcase Example: '[1,1,2]' 15 | * 16 | * Given a sorted linked list, delete all duplicates such that each element 17 | * appear only once. 18 | * 19 | * Example 1: 20 | * 21 | * 22 | * Input: 1->1->2 23 | * Output: 1->2 24 | * 25 | * 26 | * Example 2: 27 | * 28 | * 29 | * Input: 1->1->2->3->3 30 | * Output: 1->2->3 31 | * 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | /** 37 | * Definition for singly-linked list. 38 | * function ListNode(val) { 39 | * this.val = val; 40 | * this.next = null; 41 | * } 42 | */ 43 | /** 44 | * @param {ListNode} head 45 | * @return {ListNode} 46 | * @description 链表去重 当前 和 下一个 如果相等 , 将当前.next 赋值给 当前.next.next 47 | * 即完成去重 48 | */ 49 | var deleteDuplicates = function(head) { 50 | let current = head 51 | while (current && current.next) { 52 | // 当前和下一个相等 53 | if (current.val === current.next.val) { 54 | current.next = current.next.next 55 | } else { 56 | current = current.next 57 | } 58 | } 59 | return head 60 | } 61 | // @lc code=end 62 | -------------------------------------------------------------------------------- /leetcode解题/88.merge-sorted-array.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=88 lang=javascript 3 | * 4 | * [88] Merge Sorted Array 5 | * 6 | * https://leetcode.com/problems/merge-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Easy (36.83%) 10 | * Likes: 1369 11 | * Dislikes: 3187 12 | * Total Accepted: 437K 13 | * Total Submissions: 1.2M 14 | * Testcase Example: '[1,2,3,0,0,0]\n3\n[2,5,6]\n3' 15 | * 16 | * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as 17 | * one sorted array. 18 | * 19 | * Note: 20 | * 21 | * 22 | * The number of elements initialized in nums1 and nums2 are m and n 23 | * respectively. 24 | * You may assume that nums1 has enough space (size that is greater or equal to 25 | * m + n) to hold additional elements from nums2. 26 | * 27 | * 28 | * Example: 29 | * 30 | * 31 | * Input: 32 | * nums1 = [1,2,3,0,0,0], m = 3 33 | * nums2 = [2,5,6], n = 3 34 | * 35 | * Output: [1,2,2,3,5,6] 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | /** 41 | * @param {number[]} nums1 42 | * @param {number} m 43 | * @param {number[]} nums2 44 | * @param {number} n 45 | * @return {void} Do not return anything, modify nums1 in-place instead. 46 | */ 47 | var merge = function(nums1, m, nums2, n) { 48 | // 暴力解法 由于是 有序数组 删除 0 的下标 合并起来 拍一次序 49 | nums1.splice(m, nums1.length - m) 50 | nums2.splice(n, nums2.length - n) 51 | Object.assign(nums1, [...nums1, ...nums2].sort((a, b) => a - b)) 52 | } 53 | // @lc code=end 54 | -------------------------------------------------------------------------------- /leetcode解题/9.palindrome-number.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=9 lang=javascript 3 | * 4 | * [9] Palindrome Number 5 | * 6 | * https://leetcode.com/problems/palindrome-number/description/ 7 | * 8 | * algorithms 9 | * Easy (44.86%) 10 | * Likes: 1623 11 | * Dislikes: 1378 12 | * Total Accepted: 677.4K 13 | * Total Submissions: 1.5M 14 | * Testcase Example: '121' 15 | * 16 | * Determine whether an integer is a palindrome. An integer is a palindrome 17 | * when it reads the same backward as forward. 18 | * 19 | * Example 1: 20 | * 21 | * 22 | * Input: 121 23 | * Output: true 24 | * 25 | * 26 | * Example 2: 27 | * 28 | * 29 | * Input: -121 30 | * Output: false 31 | * Explanation: From left to right, it reads -121. From right to left, it 32 | * becomes 121-. Therefore it is not a palindrome. 33 | * 34 | * 35 | * Example 3: 36 | * 37 | * 38 | * Input: 10 39 | * Output: false 40 | * Explanation: Reads 01 from right to left. Therefore it is not a 41 | * palindrome. 42 | * 43 | * 44 | * Follow up: 45 | * 46 | * Coud you solve it without converting the integer to a string? 47 | * 48 | */ 49 | /** 50 | * @param {number} x 51 | * @return {boolean} 52 | */ 53 | var isPalindrome = function(x) { 54 | const repeat = String(x) 55 | .split('') 56 | .reverse() 57 | .join('') 58 | return repeat == x 59 | } 60 | -------------------------------------------------------------------------------- /leetcode解题/压缩字符串.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 压缩字符串 3 | * @description aaaabcccaaa => a4bc3a3 4 | */ 5 | 6 | const reduceString = str => { 7 | const len = str.length; 8 | let [index, num, temp] = [0, 1, ""]; 9 | 10 | while (index < len) { 11 | //如果前后两个值一样 数量+1 12 | if (str.charAt(index) === str.charAt(index + 1)) { 13 | num++; 14 | } else { 15 | //如果不一样 就 加上当前的数量 数量 设为初始值 1 16 | temp += str.charAt(index); 17 | if(num>1){ 18 | temp += num; 19 | } 20 | num = 1; 21 | } 22 | index++; 23 | } 24 | return temp; 25 | }; 26 | 27 | 28 | console.log(reduceString("aaaabcccaaa")); //a4bc3a3 -------------------------------------------------------------------------------- /memoize.js: -------------------------------------------------------------------------------- 1 | // 缓存函数计算结果 2 | 3 | function memoize(fn) { 4 | const cache = new Map(); 5 | return (num) => { 6 | if (cache.has(num)) { 7 | console.log('cache', num); 8 | return cache.get(num); 9 | } 10 | console.log('new', num); 11 | const result = fn.call(this, num); 12 | cache.set(num, result); 13 | return result; 14 | }; 15 | } 16 | 17 | function add(n) { 18 | return n + 1; 19 | } 20 | 21 | const fn = memoize(add); 22 | 23 | fn(1); 24 | fn(2); 25 | fn(1); 26 | -------------------------------------------------------------------------------- /number的最大最小值.js: -------------------------------------------------------------------------------- 1 | console.log(Number.MAX_VALUE) 2 | console.log(Number.MIN_VALUE) 3 | console.log(Number.MAX_SAFE_INTEGER) 4 | console.log(Number.MIN_SAFE_INTEGER) 5 | -------------------------------------------------------------------------------- /number相关/parsetInt.js: -------------------------------------------------------------------------------- 1 | // 去除 0 开头的 2 | console.log(parseInt("01")) //1 3 | 4 | console.log(parseInt("01", 10)) //1 5 | -------------------------------------------------------------------------------- /number相关/十进制指数.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 28 | -------------------------------------------------------------------------------- /object相关/对象的引用.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 对象的引用 6 | 7 | 8 | 9 | 10 | 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-demos", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "repository": "https://github.com/lijinke666/Javascript.git", 6 | "author": "jinke.li", 7 | "license": "MIT", 8 | "scripts": { 9 | "start": "browser-sync start --server --files './*.html'", 10 | "bookmark": "bookmark -p /javascript-demos && git add ." 11 | }, 12 | "dependencies": { 13 | "@babel/core": "^7.0.0-beta.51", 14 | "j-bookmark": "^0.2.1" 15 | }, 16 | "devDependencies": { 17 | "pre-commit": "^1.2.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /parseInt.js: -------------------------------------------------------------------------------- 1 | const arr = ["1", "2", "3"] 2 | 3 | console.log( arr.map(parseInt) ) // [1, NaN, NaN] 4 | 5 | // parseInt(1, 0) 6 | // parseInt(2, 1) 7 | // parseInt(3, 2) 8 | 9 | arr.map((n,i)=>{ 10 | return parseInt(n, i) 11 | }) 12 | 13 | console.log(arr.map(Number)) // [1,2,3] 14 | -------------------------------------------------------------------------------- /passive流畅滚动/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 25 | 26 | -------------------------------------------------------------------------------- /performance.js: -------------------------------------------------------------------------------- 1 | console.log(performance.now()) 2 | console.log(performance.memory) 3 | -------------------------------------------------------------------------------- /private.js: -------------------------------------------------------------------------------- 1 | class A { 2 | #name = 1 3 | #log() { 4 | console.log(this.#name) 5 | } 6 | } 7 | 8 | const a = new A() 9 | a.#name 10 | a.#log() 11 | 12 | // # 真他妈的丑 13 | -------------------------------------------------------------------------------- /qs/JSON.parse.js: -------------------------------------------------------------------------------- 1 | const obj = { 2 | id: 1, 3 | name: "lijinke" 4 | } 5 | 6 | //通常使用 JSON.parse 的场景 7 | const str = JSON.stringify(obj) 8 | 9 | console.log(JSON.parse(str)); //{ id: 1, name: 'lijinke' } 10 | 11 | //第二个参数 可以接收一个函数 返回 key 和value 12 | 13 | const newObj = JSON.parse(str, (key, value) => { 14 | return (typeof value === "string") ? value.toUpperCase() : value 15 | }) 16 | 17 | console.log(newObj);//{ id: 1, name: 'LIJINKE' } 18 | 19 | 20 | //将对象key 下划线 转成驼峰 21 | 22 | const json = { 23 | "user_name": "李金珂", 24 | "user_age": 18 25 | } 26 | 27 | const newJson = JSON.parse( 28 | JSON 29 | .stringify(json) 30 | .replace(/_(\w)/g, (_, b) => b.toUpperCase()) 31 | ) 32 | 33 | 34 | //{ userName: '李金珂', userAge: 18 } 35 | console.log(newJson); -------------------------------------------------------------------------------- /qs/JSON.stringify.js: -------------------------------------------------------------------------------- 1 | //常用的场景 2 | 3 | const obj = { 4 | id: 1, 5 | name: "lijinke" 6 | } 7 | 8 | const str = JSON.stringify(obj) 9 | console.log(str); //{"id":1,"name":"lijinke"} 10 | 11 | 12 | //第三个字符串 间隔字符串 13 | 14 | const str2 = JSON.stringify(obj, undefined, 2) 15 | 16 | /** 17 | * 18 | * { 19 | "id": 1, 20 | "name": "lijinke" 21 | } 22 | * */ 23 | console.log(str2); 24 | console.log(JSON.stringify(obj, undefined, "666")); 25 | /** 26 | * { 27 | 666"id": 1, 28 | 666"name": "lijinke" 29 | } 30 | */ 31 | 32 | 33 | const str3 = JSON.stringify(obj, (key,value) => { 34 | return (typeof value === "string") ? value.toUpperCase() : value 35 | },2) 36 | 37 | console.log(str3); 38 | 39 | /** 40 | * { 41 | "id": 1, 42 | "name": "LIJINKE" 43 | } 44 | */ -------------------------------------------------------------------------------- /react/createElement.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |
10 | 11 | 24 | 25 | -------------------------------------------------------------------------------- /react/react.js: -------------------------------------------------------------------------------- 1 | export const ELEMENT_TYPE = { 2 | TEXT: 'TEXT_ELEMENT', 3 | }; 4 | 5 | export function createElement(type, props, ...children) { 6 | return { 7 | type, 8 | props: { 9 | ...props, 10 | // 如果子节点是文本, 直接创建一个文本虚拟dom, 后面render时直接取 nodeValue 即可 11 | children: children.map((child) => { 12 | return typeof child === 'object' ? child : createTextElement(child); 13 | }), 14 | }, 15 | }; 16 | } 17 | 18 | export function createTextElement(text) { 19 | return { 20 | type: ELEMENT_TYPE.TEXT, 21 | props: { 22 | nodeValue: text, 23 | children: [], 24 | }, 25 | }; 26 | } 27 | 28 | // children 是一个特殊的 prop, 除此之外都需要赋值给当前节点 29 | export function isProperty(key) { 30 | return key !== 'children'; 31 | } 32 | 33 | export function isListener(key) { 34 | return key.startsWith('on'); 35 | } 36 | 37 | export function render(element, container) { 38 | const dom = element.type === ELEMENT_TYPE.TEXT ? document.createTextNode('') : document.createElement(element.type); 39 | const props = element.props || {}; 40 | 41 | // 设置属性值 42 | Object.keys(props) 43 | .filter(isProperty) 44 | .forEach((attr) => { 45 | // 如果是事件, 就挂载在对应的节点上 46 | if (isListener(attr)) { 47 | const event = attr.replace('on', '').toLowerCase(); 48 | dom.addEventListener(event, props[attr]); 49 | } else { 50 | dom[attr] = props[attr]; 51 | } 52 | }); 53 | 54 | // 递归渲染子节点 55 | element.props.children.forEach((child) => { 56 | render(child, dom); 57 | }); 58 | 59 | container.appendChild(dom); 60 | } 61 | 62 | export default { 63 | createElement, 64 | render, 65 | }; 66 | -------------------------------------------------------------------------------- /react/useState.js: -------------------------------------------------------------------------------- 1 | const render = () => { 2 | console.log('render...') 3 | } 4 | let v 5 | const useState = value => { 6 | v = v | value 7 | const set = newValue => { 8 | v = newValue 9 | render() 10 | } 11 | 12 | return [v, set] 13 | } 14 | 15 | const [value, setValue] = useState(1) 16 | console.log('value: ', value) 17 | setValue(2) 18 | console.log('value: ', value) 19 | -------------------------------------------------------------------------------- /react为什么要super(props)/index.js: -------------------------------------------------------------------------------- 1 | class Component { 2 | constructor(props){ 3 | this.props = props 4 | console.log(this.state); 5 | } 6 | } 7 | 8 | class B extends Component { 9 | // 如果 使用 类 属性 就可以避免这种 问题 10 | state = { 11 | name: '' 12 | } 13 | constructor(props){ 14 | // this.test() 15 | // 如果未 使用 super() 使用 this 会报错, 是因为 要等父类 constructor 完成 16 | // Must call super constructor in derived class before accessing 'this' or returning from derived constructor 17 | 18 | // 使用 super 传值 给父 类 19 | 20 | // 如果 super 没传值 21 | // super() 22 | 23 | // console.log(props); // 李金珂 24 | // console.log(this.props); // undefined 25 | 26 | 27 | super(props) 28 | 29 | console.log(props); // 李金珂 30 | console.log(this.props); // 李金珂 31 | } 32 | test(){ 33 | console.log('test'); 34 | } 35 | } 36 | 37 | new B('李金珂') -------------------------------------------------------------------------------- /replaceAll.js: -------------------------------------------------------------------------------- 1 | console.log("a,b,c".replaceAll(',','|')) 2 | console.log("a,b,c".replace(',','|')) 3 | -------------------------------------------------------------------------------- /serviceWorker获取资源http状态码/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |

hello

11 | 12 | 13 | 25 | 26 | -------------------------------------------------------------------------------- /serviceWorker获取资源http状态码/index.js: -------------------------------------------------------------------------------- 1 | console.log('test js file') 2 | -------------------------------------------------------------------------------- /serviceWorker获取资源http状态码/sw.js: -------------------------------------------------------------------------------- 1 | self.addEventListener('fetch', (event) => { 2 | event.waitUntil( 3 | (async function() { 4 | if (!event.clientId) return 5 | 6 | const client = await clients.get(event.clientId) 7 | if (!client) return 8 | 9 | return fetch(event.request.url).then((res) => 10 | // 发送状态码给 客户端 11 | client.postMessage(res.status) 12 | ) 13 | })() 14 | ) 15 | }) 16 | -------------------------------------------------------------------------------- /setTimeout的第三个参数.js: -------------------------------------------------------------------------------- 1 | function say() { 2 | setTimeout((...args) => console.log(args), 500, '1',2,3) 3 | } 4 | 5 | say() 6 | 7 | // ["1", 2, 3] 8 | -------------------------------------------------------------------------------- /testPostMessage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /this相关/this是如何工作的/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * this 永远指向函数运行时所在的对象,而不是函数创建时所在的对象 4 | 匿名函数和不处于任何对象中的函数,This指向window 5 | call, apply, with指的This是谁就是谁。 6 | 普通函数调用,函数被谁调用,This就指向谁 7 | */ 8 | 9 | var a = 0; 10 | 11 | var obj = { 12 | a: 1, 13 | test() { 14 | console.log(this.a); 15 | } 16 | }; 17 | 18 | obj.test(); // 1. this指向函数运行时所在的对象 当前this 是 obj 19 | 20 | var b = obj.test; 21 | 22 | b(); 23 | -------------------------------------------------------------------------------- /trim.js: -------------------------------------------------------------------------------- 1 | const str = " 李 金 珂 " 2 | 3 | console.log(str.trim()); 4 | 5 | String.prototype._trim = function(){ 6 | return this.replace(/\s/g,"") 7 | } 8 | 9 | console.log(str._trim()); -------------------------------------------------------------------------------- /uuid.js: -------------------------------------------------------------------------------- 1 | const uid = () => { 2 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 3 | var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); 4 | return v.toString(16); 5 | }); 6 | } 7 | 8 | console.log(uid()); -------------------------------------------------------------------------------- /valueOf和toString.js: -------------------------------------------------------------------------------- 1 | console.log(1 + ""); 2 | 3 | // 在隐式转换时,会触发内部的 valueOf 4 | 5 | // 实际 1 => new Number(1) 6 | 7 | const a = new Number(1); 8 | 9 | a.valueOf = () => { 10 | return "ljk"; 11 | }; 12 | 13 | console.log(a + ""); // ljk 14 | 15 | const obj = { 16 | toString() { 17 | return "ljk"; 18 | }, 19 | valueOf() { 20 | return "我是你爹"; 21 | } 22 | }; 23 | 24 | console.log(obj + ""); // 我是你爹 25 | 26 | // 用 String 强制类型转换时 会触发内部的 toString 方法 27 | console.log(String(obj)); // ljk 28 | -------------------------------------------------------------------------------- /webAnimationApi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | web animation api 9 | 24 | 25 | 26 | 27 | 28 | 29 |
赵日天
30 | 31 | 53 | 54 | -------------------------------------------------------------------------------- /~运算符.js: -------------------------------------------------------------------------------- 1 | // ~ 是一个隐式转换操作符 2 | 3 | // ~42 = -(42+1) 4 | 5 | console.log(~42); // -43 6 | 7 | // 一个骚操作 用于 indexOf 8 | console.log("a".indexOf("b")); // -1 9 | 10 | // 通常是 11 | if ("a".indexOf("b") !== -1) { 12 | console.log("做一些事"); 13 | } 14 | 15 | // 可以用 ~ 16 | 17 | if (~"a".indexOf("a")) { 18 | console.log("做一些事"); 19 | } 20 | 21 | // 两个~~ 是元运算 可以用来取整 22 | console.log(~~1.0); // 1 23 | -------------------------------------------------------------------------------- /一些新的原生api/Fetch请求.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 24 | -------------------------------------------------------------------------------- /一些新的原生api/Notification通知API.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 47 | -------------------------------------------------------------------------------- /一些新的原生api/URL.createObjectURL() 生成excel文件.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |

HTML5 的 download 属性 ,new Blob() 对象 URL.createObjectURL() 结合实现文件下载

11 | 下载excel文件 12 | 下载图片 13 | 14 | 26 | -------------------------------------------------------------------------------- /一些新的原生api/intersectionObserver.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 监听dom是否在容器可视范围内 8 | 19 | 20 | 21 |
22 | 23 |
24 | 25 | 44 | -------------------------------------------------------------------------------- /一些新的原生api/postMessage().html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | postMessage 跨页面跨域传输消息 8 | 9 | 10 |
11 | 12 |
13 | 14 | 19 | -------------------------------------------------------------------------------- /一些新的原生api/requestIdleCallback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | requestIdleCallback 8 | 9 | 10 |

11 | window.requestIdleCallback()会在浏览器空闲时期依次调用函数, 这就可以让开发者在主事件循环中执行后台或低优先级的任务,而且不会对像动画和用户交互这样延迟触发而且关键的事件产生影响。函数一般会按先进先调用的顺序执行,除非函数在浏览器调用它之前就到了它的超时时间。 12 |

13 | 14 | 33 | -------------------------------------------------------------------------------- /一些新的原生api/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/一些新的原生api/test.jpg -------------------------------------------------------------------------------- /三角函数实际应用/跟随鼠标旋转(atan2).html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 跟随鼠标旋转.html 7 | 30 | 31 | 32 |
1
33 | 34 | 46 | 47 | -------------------------------------------------------------------------------- /下划线驼峰互转/index.js: -------------------------------------------------------------------------------- 1 | const name = 'user_name' 2 | 3 | const toHump = (name)=> name.replace(/_(\w)/g,(_,b )=> b.toUpperCase()) 4 | 5 | console.log(toHump(name)); //userName 6 | console.log(toHump("user_name_pass_word")); //userNamePassWord 7 | 8 | 9 | //驼峰 => 下划线 10 | 11 | const toUnderLine = (name)=> name.replace(/([A-Z])/g,(_,b)=> `_${b.toLowerCase()}`) 12 | 13 | console.log(toUnderLine('userName')); //user_name 14 | console.log(toUnderLine('userNamePassWord')); //user_name_pass_word 15 | -------------------------------------------------------------------------------- /下载.js: -------------------------------------------------------------------------------- 1 | export const downloadFile = (data, { filename }) => { 2 | const blob = new Blob([`\ufeff${data}`], { 3 | type: 'charset=UTF-8', 4 | }); 5 | const url = URL.createObjectURL(blob); 6 | const link = document.createElement('a'); 7 | link.style.display = 'none'; 8 | link.download = filename; 9 | link.href = url; 10 | document.body.appendChild(link); 11 | link.click(); 12 | URL.revokeObjectURL(url); 13 | link.remove(); 14 | }; 15 | -------------------------------------------------------------------------------- /丝滑的回到顶部/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 18 | 19 | 20 |

window.scrollTop

21 |
1
22 | 23 | 24 | 33 | 34 | -------------------------------------------------------------------------------- /中文首字母拼音排序.js: -------------------------------------------------------------------------------- 1 | ['张三','李四','刘能','阿祖'].sort(new Intl.Collator('zh').compare) 2 | 3 | // ["阿祖", "李四", "刘能", "张三"] 4 | -------------------------------------------------------------------------------- /中断 fetch 请求/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 36 | 37 | -------------------------------------------------------------------------------- /代理/defineProperty.js: -------------------------------------------------------------------------------- 1 | const obj = {}; 2 | Object.defineProperty(obj, "test", { 3 | configurable: true, //是否可配置 4 | // writable:true, //是否可写 false 为只读 5 | enumerable: true, //是否可枚举 6 | //get 和 set 相当于代理函数 test 属性更改时 会触发 7 | set(value) { 8 | console.log("set:", value); 9 | } 10 | }); 11 | 12 | console.log(obj); //{test:1} 13 | 14 | obj.test = 2; 15 | console.log(obj.test); 16 | 17 | 18 | //调用一个 废弃的api时 给出警告 19 | const testAPis = ['apia','apib','apic'] 20 | class Test {} 21 | 22 | testAPis.forEach((key)=>{ 23 | Object.defineProperty(global,key,{ 24 | configurable:true, 25 | enumerable:true, 26 | get(){ 27 | console.warn(`${key} 已经废弃了!`); 28 | } 29 | }) 30 | }) 31 | 32 | global.apia 33 | -------------------------------------------------------------------------------- /代理/reflect.js: -------------------------------------------------------------------------------- 1 | const obj = {} 2 | //和 Object.defineProperty 基本一样 3 | Reflect.defineProperty(obj,'$vue',{ 4 | configurable: true, //是否可配置 5 | enumerable: true, //是否可枚举 6 | 7 | set(value) { 8 | console.log("set:", value); 9 | } 10 | }) 11 | 12 | obj.$vue 13 | 14 | obj.$vue = 'test' 15 | -------------------------------------------------------------------------------- /代理/双向数据绑定1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Object.defineProperty()双向数据绑定 9 | 10 | 11 | 12 | 13 | 14 | 15 | 29 | 30 | -------------------------------------------------------------------------------- /低级/onunload卸载事件.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

当页面刷新,或者页面关闭时,触发onunload事件

9 | 10 | 16 | -------------------------------------------------------------------------------- /低级/setAttribute 属性.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 无标题文档 6 | 7 | 8 |

我的课程

9 | 16 |

以下为li列表title的值,当title为空时,新设置值为"WEB前端技术":

17 | 31 | 32 | -------------------------------------------------------------------------------- /低级/什么是对象.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 什么是对象 6 | 11 | 12 | 13 |

什么是对象

14 | JavaScript 中的所有事物都是对象,如:字符串、数值、数组、函数等,每个对象带有属性和方法。 15 |

对象的属性

反映该对象某些特定的性质的,如:字符串的长度、图像的长宽等; 16 |

对象的方法

能够在对象上执行的动作。例如,表单的“提交”(Submit),时间的“获取”(getYear)等; 17 | JavaScript 提供多个内建对象,比如 String、Date、Array 等等,使用对象前先定义,如下使用数组对象: 18 | var objectName =new Array();//使用new关键字定义对象 19 | 或者 20 | var objectName =[]; 21 |

访问对象属性的语法

22 | objectName.propertyName 23 | 如使用 Array 对象的 length 属性来获得数组的长度: 24 | var myarray=new Array(6);//定义数组对象 25 | var myl=myarray.length;//访问数组长度length属性 26 | 以上代码执行后,myl的值将是:6 27 |

访问对象的方法

28 | objectName.methodName() 29 |

如使用string 对象的 toUpperCase() 方法来将文本转换为大写

30 | var mystr="Hello world!";//创建一个字符串 31 | var request=mystr.toUpperCase(); //使用字符串对象方法 32 | 以上代码执行后:HELLO WORLD! 33 | 34 | 47 | -------------------------------------------------------------------------------- /低级/兄弟节点.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

9 | 10 | 元素类型 节点类型 11 | 12 | 元素 1 13 | 14 | 属性 2 15 | 16 | 文本 3 17 | 18 | 注释 8 19 | 20 | 文档 9 21 |

22 | 30 | 35 | 36 | 63 | -------------------------------------------------------------------------------- /低级/删除节点.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 无标题文档 6 | 7 | 8 | 9 |
10 |

html

11 |

php

12 |

javascript

13 |

jquery

14 |

java

15 |
16 | 17 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /低级/判断当前是什么浏览器.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | navigator 6 | 21 | 22 | 23 |
24 | 25 |
26 | 27 | -------------------------------------------------------------------------------- /低级/复选框全选.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/低级/复选框全选.html -------------------------------------------------------------------------------- /低级/数组.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 43 | -------------------------------------------------------------------------------- /低级/日期小练习.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 系好安全带,准备启航 6 | 7 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /低级/替换节点.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 无标题文档 6 | 7 | 8 |

替换节点时,原来的节点里面的所有属性也会被替换掉

9 | 10 |
JavaScript是一个很常用的技术,为网页添加动态效果。
11 | 将加粗改为斜体 12 | 13 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /低级/节点综合练习【table表格】.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/低级/节点综合练习【table表格】.html -------------------------------------------------------------------------------- /低级/返回上一级页面.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

操作成功

9 | 10 | 返回 11 | 12 | 27 | -------------------------------------------------------------------------------- /低级/返回值.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 24 | -------------------------------------------------------------------------------- /作用域/index.js: -------------------------------------------------------------------------------- 1 | function a() { 2 | var b = 1; 3 | function bb() { 4 | var b = 2; 5 | console.log(b); 6 | } 7 | bb(); 8 | } 9 | 10 | a(); 11 | -------------------------------------------------------------------------------- /你还可以输入多少字.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 28 | 29 | 30 |
31 | 32 |

你还可以输入个字

33 | 34 | 56 | -------------------------------------------------------------------------------- /使用 setPointerCapture 实现拖拽.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | setPointerCapture 实现拖拽 7 | 19 | 20 | 21 |
拖我
22 | 23 | 46 | 47 | -------------------------------------------------------------------------------- /元素focus后页面不滚动/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 34 | 35 | -------------------------------------------------------------------------------- /元素滚动在可视范围.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 19 | 20 | 21 | 22 | 23 | 24 |

25 |
div1
26 |
div2
27 | 28 | 39 | 40 | -------------------------------------------------------------------------------- /函数式编程/偏函数/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 偏函数 3 | * @desc 类似于 工厂函数 封装一层 重复的代码 按给定的 类型 返回对应的工厂函数 4 | */ 5 | 6 | const isType = (type)=> (value)=> Object.is(typeof (value),type) 7 | 8 | const isString = isType('string') 9 | const isNumber = isType('number') 10 | 11 | console.log(isString("1")); //true 12 | console.log(isNumber(1)); //true -------------------------------------------------------------------------------- /函数式编程/尾调用/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 尾调用 3 | * @url http://www.ruanyifeng.com/blog/2015/04/tail-call.html 4 | * 指某个函数的最后一步是调用另一个函数。 5 | */ 6 | 7 | //尾调用 8 | const log = (...text) => console.log(...text) 9 | 10 | function mylog(...text) { 11 | log(...text) 12 | } 13 | 14 | mylog('哈哈', '嘻嘻') //哈哈 嘻嘻 15 | 16 | 17 | // 18 | function factorial(n) { 19 | if (n === 1) return 1; 20 | return n * factorial(n - 1); 21 | } 22 | 23 | const num1 = factorial(3) 24 | console.log(num1); //6 25 | 26 | { 27 | function factorial(n, total = 1) { 28 | if (n === 1) return total; 29 | return factorial(n - 1, n * total); 30 | } 31 | factorial(5) // 120 32 | } -------------------------------------------------------------------------------- /函数式编程/柯里化/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 柯里化 3 | * 是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数 4 | * 并且返回接受余下的参数而且返回结果的新函数的技术 5 | * 6 | */ 7 | 8 | const add = (num1)=> (num2) => { 9 | return num1 + num2 10 | } 11 | 12 | const num = add(1)(2) 13 | console.log(num); //3 14 | 15 | //等同于 16 | 17 | function add2(num1){ 18 | return function(num2){ 19 | return num1 + num2 20 | } 21 | } 22 | 23 | 24 | /** 25 | * 我说用到的 实际场景 26 | * 输出一段文案 如 createTip() 之前都是 标准的 前x个盲注 27 | * 后有需求 有 前x个盲注 和 第x个盲注 28 | */ 29 | 30 | // const text = (num=1)=> `第${num}个盲注!` 31 | 32 | //后改为 33 | const text = (num)=> `${num}个盲注` 34 | 35 | 36 | const createTip = (suffix)=> (num)=> suffix + text(num) 37 | 38 | const tip1 = createTip('第')(10) 39 | const tip2 = createTip('前')(6) 40 | 41 | //可在源代码不变的情况下进行扩充 每一个函数负责独立的单一功能 42 | 43 | console.log(tip1,tip2); //第10个盲注 前6个盲注 -------------------------------------------------------------------------------- /函数式编程/管道-pipe/index.js: -------------------------------------------------------------------------------- 1 | const add = (a) => a + 2 2 | const subtract = (a) => a - 1 3 | 4 | // 普通的 柯里化 5 | 6 | subtract(add(1)) // 1 7 | 8 | // 这样会有一个问题 , 包裹很多层后 代码不可读 9 | 10 | const pipe = (...args) => defaultValue => args.reduce((outputValue, currentFunction) => currentFunction(outputValue), defaultValue) 11 | 12 | const num = pipe( 13 | add, 14 | subtract 15 | ) 16 | 17 | console.log(num(10)) // => subtract(add(10)) //11 18 | 19 | // 10 |> add |> subtract -------------------------------------------------------------------------------- /函数式编程/组合-compose/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 将多个函数组合成一个函数, 依次执行 3 | * @param {...any} fns 4 | */ 5 | 6 | function compose(...fns) { 7 | return (...args) => fns.reduce((currentArgs, fn) => fn(currentArgs), ...args) 8 | } 9 | 10 | function a(param) { 11 | return `${param}-李` 12 | } 13 | function b(param) { 14 | return `${param}-金` 15 | } 16 | function c(param) { 17 | return `${param}-珂` 18 | } 19 | const fn = compose( 20 | a,b,c 21 | ) 22 | console.log(fn('骚猪')); // 骚猪-李-金-珂 23 | -------------------------------------------------------------------------------- /函数式编程/自动柯里化/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 自动柯里化 3 | */ 4 | 5 | const curry = (fn) => { 6 | const _curry = (restNum = 0, args = []) => { 7 | if (restNum === 0) { // 如果只有一个参数 就直接调用 8 | return fn(...args) 9 | } 10 | // 如果有多个参数 递归调用 直到 参数为 0 11 | return (params) => _curry(restNum - 1, [...args, params]) 12 | } 13 | return _curry(fn.length) // 传入函数的参数的长度 觉得执行几次 14 | } 15 | 16 | const test = curry((a, b, c) => a + b + c) 17 | const test2 = curry((a, b) => a ** b) 18 | 19 | console.log(test(1)(2)(3)); // 6 20 | console.log(test2(1)(2)); // 1 21 | console.log(test2(3)(3)); // 3 * 3 * 3 = 27 22 | -------------------------------------------------------------------------------- /函数式编程/高阶函数/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 高阶函数 3 | * @desc 可以把函数当做参数 或者返回值 4 | */ 5 | 6 | //返回值为函数 7 | const fn = (num)=> ()=> num 8 | 9 | console.log(fn(1)()) //1 10 | 11 | 12 | //函数当参数 13 | const arr = [1,3,4,2] 14 | arr.sort((a,b)=> a+b) -------------------------------------------------------------------------------- /判断节点之间的位置/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
c
11 |
2
12 | 13 | 24 | 25 | -------------------------------------------------------------------------------- /利用blob将文本保存为html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 14 | 15 | 16 | 30 | 31 | 32 | 46 | -------------------------------------------------------------------------------- /刷新页面不记住滚动位置.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 刷新页面不记住滚动位置 8 | 9 | 10 |
11 | 12 |
13 | 14 | 24 | 25 | -------------------------------------------------------------------------------- /前端常用算法/二叉树节点总和.js: -------------------------------------------------------------------------------- 1 | const tree = { 2 | val: 1, 3 | left: { 4 | val: 2, 5 | left: { 6 | val: 4, 7 | left: null, 8 | right: null, 9 | }, 10 | right: { 11 | val: 5, 12 | left: null, 13 | right: null, 14 | }, 15 | }, 16 | right: { 17 | val: 3, 18 | left: null, 19 | right: null, 20 | }, 21 | } 22 | 23 | 24 | function countTree(root, sum = 0) { 25 | if (!root) { 26 | return 0 27 | } 28 | sum+=root.val 29 | if (!root.left && !root.right) { 30 | return sum 31 | } 32 | return root.val + countTree(root.left, sum) + countTree(root.right, sum) 33 | } 34 | 35 | console.log(countTree(tree)); 36 | -------------------------------------------------------------------------------- /前端常用算法/二路归并.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 二路归并 3 | * @param {*} left 4 | * @param {*} right 5 | */ 6 | function merge(left, right) { 7 | var result = [], 8 | il = 0, 9 | ir = 0; 10 | 11 | while (il < left.length && ir < right.length) { 12 | if (left[il] < right[ir]) { 13 | result.push(left[il++]); 14 | } else { 15 | result.push(right[ir++]); 16 | } 17 | } 18 | while(left[il]){ 19 | result.push(left[il++]); 20 | } 21 | while(right[ir]){ 22 | result.push(right[ir++]); 23 | } 24 | return result; 25 | } -------------------------------------------------------------------------------- /前端常用算法/公共前缀.js: -------------------------------------------------------------------------------- 1 | function longestCommonPrefix(arr) { 2 | let result = "" 3 | for (let i = 0; i < arr.length; i++) { 4 | const current = arr.map((v) => v.substr(i, 1)) 5 | const unique = [...new Set(current)] 6 | if (unique.length !== 1) { 7 | break 8 | } 9 | result += current[0] 10 | } 11 | 12 | return result 13 | } 14 | 15 | console.log(longestCommonPrefix(['flower', 'flow', 'flight'])) 16 | console.log(longestCommonPrefix(['my', 'my', 'my'])) 17 | console.log(longestCommonPrefix(['my', 'test', '111'])) 18 | -------------------------------------------------------------------------------- /前端常用算法/删除1个数字后的最小值.js: -------------------------------------------------------------------------------- 1 | const deleteNumber = (number) => { 2 | // 如果 第一位 比 第 二位 大 那就删除第一位 否则相反 3 | const first = number.charAt(0) 4 | const second = number.charAt(1) 5 | 6 | if(first >= second) { 7 | return number.substring(1) 8 | } 9 | 10 | return number.substr(0,1) + number.substr(2, number.length) 11 | } 12 | 13 | console.log(deleteNumber("541270936")); //41270936 14 | console.log(deleteNumber("451270936")); //41270936 15 | -------------------------------------------------------------------------------- /前端常用算法/判断一个数是否为 2 的整数次幂.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 2 * 2 * 2 = 8 3 | * 8 就是 2 的 整数次幂 4 | * @param {*} num 5 | */ 6 | 7 | const isPowerOf2 = (num) => { 8 | let temp = 1 9 | while (temp <= num) { 10 | if (temp === num) { 11 | return true 12 | } 13 | temp = temp * 2 14 | } 15 | return false 16 | } 17 | 18 | console.log(isPowerOf2(10)) // false 19 | console.log(isPowerOf2(8)) // true 20 | console.log(isPowerOf2(4)) // true 21 | 22 | 23 | // 位运算 24 | const isPowerOf2Version2 = (num) => { 25 | return (num & num - 1) === 0 26 | } 27 | 28 | console.log(isPowerOf2Version2(10)) // false 29 | console.log(isPowerOf2Version2(8)) // true 30 | console.log(isPowerOf2Version2(4)) // true 31 | 32 | -------------------------------------------------------------------------------- /前端常用算法/压缩字符串.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 压缩字符串 3 | * @description aaaabcccaaa => a4bc3a3 4 | */ 5 | 6 | const reduceString = (str)=>{ 7 | let num = 0 8 | return Array(str.length).fill().reduce((temp,v,i,arr)=>{ 9 | if(str.charAt(i) === str.charAt(i+1)){ 10 | num++ 11 | }else{ 12 | temp+= str.charAt(i); //如果前后不一样 就加上当前字符 13 | num >0 && (temp+=num) //如果有重复的就加上重复的数字 14 | num = 0 //还原,重新开始计算 15 | } 16 | return temp 17 | },"") 18 | } 19 | 20 | console.log(reduceString("aaaabcccaaa")); 21 | console.log(reduceString("aabbbbbbbbcccaaa")); 22 | console.log(reduceString("fffaccccdd")); -------------------------------------------------------------------------------- /前端常用算法/大数相加.js: -------------------------------------------------------------------------------- 1 | function bigNumberSum(a, b) { 2 | 3 | // padding 4 | let cur = 0; 5 | while (cur < a.length || cur < b.length) { 6 | if (!a[cur]) { 7 | a = "0" + a; 8 | } else if (!b[cur]) { 9 | b = "0" + b; 10 | } 11 | cur++; 12 | } 13 | 14 | let carried = 0; 15 | const res = []; 16 | 17 | for (let i = a.length - 1; i > -1; i--) { 18 | const sum = carried + +a[i] + +b[i]; 19 | if (sum > 9) { 20 | carried = 1; 21 | } else { 22 | carried = 0; 23 | } 24 | res[i] = sum % 10; 25 | } 26 | if (carried === 1) { 27 | res.unshift(1); 28 | } 29 | 30 | return res.join(""); 31 | } 32 | -------------------------------------------------------------------------------- /前端常用算法/字符串反转.js: -------------------------------------------------------------------------------- 1 | // 传统利用数组 2 | function reverseString(str) { 3 | return str.split('').reverse().join('') 4 | } 5 | 6 | console.log(reverseString('abc')); // cba 7 | console.log(reverseString('李金珂')) // 珂金李 8 | 9 | console.log(reverseString('😃👀')) // 一个emoji占两个字符 所以无效 10 | 11 | 12 | // 利用 Array.from() 规避 13 | 14 | console.log('😃'.length); // 2 15 | console.log(Array.from('😃').length) // 1 16 | 17 | 18 | function reverseString2(str) { 19 | return Array.from(str).reverse().join('') 20 | } 21 | 22 | console.log(reverseString2('abc')); // cba 23 | console.log(reverseString2('李金珂')) // 珂金李 24 | 25 | console.log(reverseString2('😃👀')) // 一个emoji占两个字符 所以无效 26 | 27 | 28 | // 第二种 递归的方式 29 | 30 | function reverseString3(str) { 31 | // 解决 emoji 32 | const strs = Array.from(str) 33 | 34 | if (strs.length === 1) { 35 | return str 36 | } 37 | 38 | // 依次取第一个放在最后面 39 | return reverseString3(strs.slice(1)) + strs[0] 40 | } 41 | 42 | console.log(reverseString3('abc')); // cba 43 | console.log(reverseString3('李金珂')) // 珂金李 44 | console.log(reverseString3('😃👀')) // 一个emoji占两个字符 所以无效 45 | 46 | 47 | // 第三种 循环 48 | 49 | function reverseString4(str) { 50 | const strs = Array.from(str) 51 | return strs.reduceRight((s, v) => { 52 | s += v 53 | return s 54 | },'') 55 | } 56 | 57 | console.log(reverseString4('abc')); // cba 58 | console.log(reverseString4('李金珂')) // 珂金李 59 | console.log(reverseString4('😃👀')) // 一个emoji占两个字符 所以无效 60 | -------------------------------------------------------------------------------- /前端常用算法/寻找缺失整数.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 一个无序数组里有 99 个不重复的正整数, 范围 1 - 100 找到缺少的整数 3 | * @description 时间复杂度 O(1) 空间复杂度 O(n) 4 | * @param {*} arr 5 | */ 6 | 7 | const findNumberOfArray = (arr) => { 8 | const hash = new Map() 9 | Array.from({ length: 100 }).forEach((_, i) => { 10 | const key = i + 1 11 | hash.set(key, key) 12 | }) 13 | 14 | arr.forEach(item => { 15 | hash.delete(Number(item)) 16 | }) 17 | 18 | return hash.keys() 19 | } 20 | 21 | const arr = Object.keys(Array.from({ length: 100 })) 22 | arr.splice(0, 1) 23 | console.log(findNumberOfArray(arr)) // 100 24 | 25 | 26 | /** 27 | * @description 第二种解法 先算出 1+2+3...+100 累加和, 依次减去数组里的元素,得到的差值就是缺失的整数 28 | * @description 时间复杂度 O(n) 空间复杂度 O(1) 29 | */ 30 | const findNumberOfArray2 = (arr) => { 31 | const max = Object.keys(Array.from({ length: 100 })).reduce((n, value)=>{ 32 | n += Number(value) 33 | return n 34 | },0) 35 | 36 | 37 | const min = arr.reduce((n, value)=>{ 38 | n += Number(value) 39 | return n 40 | },0) 41 | 42 | return max - min 43 | } 44 | 45 | console.log(findNumberOfArray2(arr)) 46 | -------------------------------------------------------------------------------- /前端常用算法/找出重复数字.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 找出重复数字 3 | * @param {...number} num 4 | */ 5 | 6 | // 双重循环 暴力版 时间复杂度 O(n^2) 耗时: 0.1s 7 | const repeat = (...num) => { 8 | const validatedNum = [] 9 | const repeatNum = [] 10 | for (let i = 0; i <= num.length; i++) { 11 | if(!validatedNum.includes(num[i])) { 12 | validatedNum.push(num[i]) 13 | } else { 14 | repeatNum.push(num[i]) 15 | } 16 | } 17 | return repeatNum 18 | } 19 | 20 | // console.log(repeat(3, 1, 2, 5, 4, 9, 7, 2)) // [2] 21 | // console.log(repeat(3, 1, 2, 5, 4, 9, 7, 2, 1)) // [2,1] 22 | 23 | 24 | // 通过字典来 优化 时间复杂度 O(n) 耗时: 0.096s 25 | const repeatByDict = (...num) => { 26 | // 这里用字典来存储 => O(1) 27 | const validatedNum = new Map() 28 | 29 | const repeatNum = [] 30 | for (let i = 0; i <= num.length; i++) { 31 | if(!validatedNum.has(num[i])) { 32 | validatedNum.set(num[i], true) 33 | } else { 34 | repeatNum.push(num[i]) 35 | } 36 | } 37 | return repeatNum 38 | } 39 | 40 | console.log(repeatByDict(3, 1, 2, 5, 4, 9, 7, 2)) // [2] 41 | console.log(repeatByDict(3, 1, 2, 5, 4, 9, 7, 2, 1)) // [2,1] 42 | -------------------------------------------------------------------------------- /前端常用算法/找到最大的数.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @description 一组整数, 找到最大的数 类似 Math.max() 4 | * @param {...number} num 5 | */ 6 | const max = (...num) => { 7 | if(num === 1) { 8 | return num[0] 9 | } 10 | let result = num[0] 11 | for(let i = 1; i< num.length; i++) { 12 | if(num[i] > result) { 13 | result = num[i] 14 | } 15 | } 16 | return result 17 | } 18 | 19 | 20 | console.log(max(1, 100, 20, 99, 3)) 21 | console.log(max(3)) 22 | console.log(max(200,100)) 23 | -------------------------------------------------------------------------------- /前端常用算法/插入排序.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 插入排序 3 | */ 4 | 5 | const insertSort = (arr = []) => { 6 | const len = arr.length; 7 | let temp; 8 | //第一个默认已经排序 所以 i=1 从第一个开始 9 | for (let i = 1; i < len; i++) { 10 | //如果当前元素 大于了 前一个元素 就交换位置 11 | for (let j = i; j > 0 && arr[j] - arr[j - 1] < 0; j--) { 12 | temp = arr[j]; 13 | arr[j] = arr[j - 1]; 14 | arr[j - 1] = temp; 15 | } 16 | } 17 | return arr; 18 | }; 19 | 20 | console.log(insertSort([1, 2, 10, 3, 999, 4])); 21 | -------------------------------------------------------------------------------- /前端常用算法/数组中间插入.js: -------------------------------------------------------------------------------- 1 | const insert = (arr, value, index) => { 2 | if (index < 0 || index > arr.length) { 3 | throw new Error('invalid range!') 4 | } 5 | 6 | // 从右往左循环, 逐个向右挪一位 7 | 8 | for (let i = arr.length - 1; i >= 0; i--) { 9 | arr[i + i] = arr[i] 10 | } 11 | 12 | arr[index] = value 13 | return arr 14 | } 15 | 16 | console.log(insert([1, 2, 3], "ljk", 1)); // [1,'ljk', 2, 3] 17 | -------------------------------------------------------------------------------- /前端常用算法/斐波那契数列.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 斐波那契数列: 3 | * @description 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... 求第n个数是多少 4 | * 第一个数: 1 5 | 第二个数: 1 6 | 第三个数: 1+1 7 | 第三个数: 2+1+1 8 | 第四个数: 3+2+1+1 9 | 第五个数: 4+3+2+1+1 10 | */ 11 | 12 | //第n个数 就是 第n个数 第 前两个数之和 通过递归就算出来 13 | const fibonacci = (number) => { 14 | if (number <= 2) { 15 | return 1; 16 | } 17 | return fibonacci(number - 1) + fibonacci(number - 2) 18 | } 19 | 20 | console.log(fibonacci(5)); //5 21 | console.log(fibonacci(2)); //1 22 | console.log(fibonacci(10)); //55 23 | console.log(fibonacci(30)); //10 24 | -------------------------------------------------------------------------------- /前端常用算法/无序数组最大相邻差.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 无序数组最大相邻差 3 | * @description 通过冒泡排序 时间复杂度 O(nlogn) 空间复杂度 O(n) 4 | * @param {*} arr 5 | */ 6 | 7 | const maxDiff = (arr) => { 8 | let temp 9 | let result = 0 10 | 11 | // 先冒泡排序 12 | for (let i = 1; i < arr.length; i++) { 13 | for (let j = 0; j <= arr.length - i; j++) { 14 | if (arr[j] > arr[j + 1]) { 15 | temp = arr[j] 16 | arr[j] = arr[j + 1] 17 | arr[j + 1] = temp 18 | } 19 | } 20 | } 21 | 22 | for (let i = 0; i <= arr.length; i++) { 23 | if (arr[i] < arr[i + 1] && (arr[i + 1] - arr[i] > result)) { 24 | result = arr[i + 1] - arr[i] 25 | } 26 | } 27 | return result 28 | } 29 | 30 | // console.log(maxDiff([2, 6, 3, 4, 5, 10, 9])) // 3 31 | 32 | /** 33 | * @name 无序数组最大相邻差 34 | * @description 通过计数排序 时间复杂度 O(nlogn) 空间复杂度 O(n) 35 | * @param {*} arr 36 | */ 37 | 38 | const maxDiff2 = (arr) => { 39 | 40 | // 1. 找到最大值 max 和 最小值 min 的区间长度 k (k = max - min + 1) 41 | const [min, max] = [Math.min(...arr), Math.max(...arr)] 42 | const diff = max - min + 1 43 | let result = 0 44 | 45 | // 2. 创建一个 对应长度的空数组 46 | const diffArray = new Array(diff).fill(0) 47 | 48 | // 3. 遍历原数组, 计数 49 | for (let i = 0; i < arr.length; i++) { 50 | diffArray[arr[i] - min]++ 51 | } 52 | 53 | // 4. 统计 最大连续出现 0 值的次数 +1 即为最大差值 54 | 55 | for (let i = 0; i < diffArray.length; i++) { 56 | if (diffArray[i] === 0 || diffArray[i + 1] === 0) { 57 | result += 1 58 | } 59 | } 60 | return result 61 | } 62 | 63 | console.log(maxDiff2([2, 6, 3, 4, 5, 10, 9])); // 3 64 | -------------------------------------------------------------------------------- /前端常用算法/洗牌算法.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 洗牌算法 3 | */ 4 | 5 | const shuffle = (teams = []) => { 6 | for (let i = teams.length - 1; i >= 0; i--) { 7 | const randomIdx = Math.floor(Math.random() * (i + 1)); 8 | const itemIdx = teams[randomIdx]; 9 | teams[randomIdx] = teams[i]; 10 | teams[i] = itemIdx; 11 | } 12 | return teams; 13 | }; 14 | 15 | console.log(shuffle([1, 2, 3, 4, 5, 6])); 16 | -------------------------------------------------------------------------------- /前端常用算法/等差数列求和.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @name 等差数列求和 - 高斯算法 4 | * @description n - m 数字之和 5 | * @param {*} start 6 | * @param {*} end 7 | */ 8 | const test = (start, end) => { 9 | return (start + end ) * end / 2 10 | } 11 | 12 | 13 | console.log(test(1, 10000)) // 50005000 14 | -------------------------------------------------------------------------------- /前端常用算法/计数排序.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @name 计数排序 4 | * @description 适用于一定长度的 整数数组排序, 找到数组中的最大值, 生成相应长度的空数组 每个下标代表对应整数出现的次数 5 | * @param {*} arr 6 | */ 7 | const countSort = (arr) => { 8 | const max = Math.max(...arr) 9 | const countArray = new Array(max + 1) 10 | 11 | for(let i=0; i< arr.length; i++) { 12 | const value = arr[i] 13 | countArray[value]++ 14 | } 15 | 16 | const sortedArray = [] 17 | let index = 0 18 | 19 | for(let i =0; i< countArray.length; i ++){ 20 | for(let j=0; j< countArray[i]; j ++) { 21 | sortedArray[index++] = i 22 | } 23 | } 24 | 25 | return sortedArray 26 | } 27 | 28 | console.log(countSort([1,2,3,4,5, 2,3,4])); 29 | -------------------------------------------------------------------------------- /前端常用算法/连续子数字的最大和.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 找出连续子数字的最大和 3 | * @description 时间复杂度 O(n) 4 | * @param {*} arr 5 | * @example maxSum([1, -3, 9, 10, -2, 3, -6, 5]) => [9, 10, -2, 3] => 20 6 | */ 7 | function maxSum(arr) { 8 | let sum = arr[0] 9 | let maxSum = arr[0] 10 | 11 | for (let i = 1; i < arr.length; i++) { 12 | // 先比较第一个a和 第二个b 的和 , 如果a+b都小于 第二个的话 说明当中有负数 13 | sum = Math.max(sum + arr[i], arr[i]) 14 | maxSum = Math.max(sum, maxSum) 15 | } 16 | 17 | return maxSum 18 | } 19 | 20 | console.log(maxSum([1, -3, 9, 10, -2, 3, -6, 5])) 21 | -------------------------------------------------------------------------------- /前端常用算法/递归.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name 递归 3 | */ 4 | 5 | const recursion = (num) => { 6 | if (num === 1) return num 7 | return num * recursion(num - 1) 8 | } 9 | 10 | console.log(recursion(4)); //24 4 * 3 * 2 * 1 -------------------------------------------------------------------------------- /剪贴板.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
复制我哈哈哈哈
11 | 12 | 13 | 22 | -------------------------------------------------------------------------------- /剪贴板/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 剪贴板 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /加载中.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | document.onreadystatechange 文档加载状态 6 | 27 | 28 | 29 |
载入中
30 | 31 | 32 | 33 | 43 | -------------------------------------------------------------------------------- /原生分享 (navigator.share).html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 原生分享 navigator.share 8 | 9 | 10 | 11 | 12 | 25 | 26 | -------------------------------------------------------------------------------- /原生懒加载.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 13 | 14 | 15 |
往下滑
16 | test 17 | 18 | 28 | 29 | -------------------------------------------------------------------------------- /原生的flat函数/flat.js: -------------------------------------------------------------------------------- 1 | console.log([1,2,3,4,[2,3]].flat()); 2 | 3 | console.log([1,2,[3,[4,5]]].flat(2)); -------------------------------------------------------------------------------- /原生的flat函数/flatMap.js: -------------------------------------------------------------------------------- 1 | const arr1 = [1, 2, 3, 4]; 2 | 3 | console.log(arr1.map(x => [x * 2])) // [ [ 2 ], [ 4 ], [ 6 ], [ 8 ] ] 4 | console.log(arr1.flatMap(x => [x * 2])) // [2, 4, 6, 8] -------------------------------------------------------------------------------- /原生网页分享/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

原生分享功能, 只能通过用户点击事件触发, 且站点是 https

10 | 11 | 12 | 24 | 25 | -------------------------------------------------------------------------------- /原生获取联系人 (navigator.contacts).html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 原生获取联系人 navigator.contacts 8 | 9 | 10 | 11 | 12 | 23 | 24 | -------------------------------------------------------------------------------- /去除空格/index.js: -------------------------------------------------------------------------------- 1 | const trim = (target, fullTrim = false) => { 2 | if (!fullTrim) { 3 | return target.trim() 4 | } 5 | return target.replace(/\s/gm, '') 6 | } 7 | 8 | console.log(trim(' trim ')) 9 | console.log(trim(' tri m ', true)) 10 | console.log(trim(' tri m ', false)) 11 | -------------------------------------------------------------------------------- /去除重复字符串.js: -------------------------------------------------------------------------------- 1 | const str = new Set('aabbcc') 2 | 3 | console.log([...str].join('')) // abc 4 | -------------------------------------------------------------------------------- /双向绑定/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 |

name: {{name}}

14 | 15 |
16 | 17 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /双问号兼容性.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | ok 11 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /取色器/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 取色器 8 | 15 | 16 | 17 |

鼠标放到图片上

18 | 19 |
20 | 21 | 51 | -------------------------------------------------------------------------------- /变量提升/index.js: -------------------------------------------------------------------------------- 1 | console.log(a) // 这里不会报错 而是 undefined 2 | 3 | var a = 1 4 | 5 | // 因为实际 js 引擎会转换成 6 | 7 | var a 8 | 9 | console.log(a); 10 | 11 | a = 1 12 | -------------------------------------------------------------------------------- /只能输入整数/index.js: -------------------------------------------------------------------------------- 1 | const reg = /^-?(0|[1-9][0-9]*)?$/ 2 | 3 | console.log(reg.test('1')) // true 4 | console.log(reg.test('1-')) // false 5 | console.log(reg.test('-1')) // true 6 | console.log(reg.test('a')) // false 7 | console.log(reg.test('00')) // false 8 | console.log(reg.test('0')) // true 9 | -------------------------------------------------------------------------------- /周期性执行函数n次/index.js: -------------------------------------------------------------------------------- 1 | const create = (fn, n) => { 2 | let i = 0; 3 | const inner = (...args) => { 4 | i++ 5 | if (i > n) { 6 | return 7 | } 8 | inner.call(this, ...args) 9 | fn.call(this,...args) 10 | } 11 | return inner 12 | } 13 | 14 | function log() { 15 | console.log('log'); 16 | } 17 | const fn = create(log, 4) 18 | 19 | fn() 20 | -------------------------------------------------------------------------------- /图片放大镜封装/big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/图片放大镜封装/big.jpg -------------------------------------------------------------------------------- /图片放大镜封装/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/图片放大镜封装/small.jpg -------------------------------------------------------------------------------- /图片放大镜封装/放大镜.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 放大镜 7 | 26 | 27 | 28 | 29 | 30 | big.jpg 31 | 32 | 33 | big.jpg 34 | 35 | 36 | 37 | 38 | 48 | 49 | -------------------------------------------------------------------------------- /图片解码.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 图片解码 8 | 9 | 10 | 11 | 12 | 20 | -------------------------------------------------------------------------------- /填写银行卡4位后自动加空格.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 填写银行卡4位后自动加空格 6 | 7 | 8 | 9 | 10 | 24 | -------------------------------------------------------------------------------- /复制粘贴相关/copy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | copy 9 | 10 | 11 | 12 | 13 | 14 | 15 |
粘贴到这里
16 | 17 | 46 | 47 | -------------------------------------------------------------------------------- /复制粘贴相关/复制功能.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 13 | 14 | 15 | 16 | 17 | 31 | -------------------------------------------------------------------------------- /复制粘贴相关/获取剪贴板中的数据.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 粘贴图片 8 | 10 | 11 | 12 | 13 | 14 | 54 | -------------------------------------------------------------------------------- /字符串去重/1.js: -------------------------------------------------------------------------------- 1 | function distinct(string) { 2 | return string.replace(/(.)\1+/g, '$1') 3 | } 4 | 5 | console.log(distinct('aaaabbbbccc')); // abc -------------------------------------------------------------------------------- /字符串反转.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | const = reverseString 13 | 14 | 19 | 20 | -------------------------------------------------------------------------------- /字符串超出长度隐藏.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 18 | 19 | 20 |
21 |

22 | We need a friend but I don't need an enemy Because I don't like this 23 |

24 |
25 | 26 | 27 | 39 | -------------------------------------------------------------------------------- /实现一个instanceof/index.js: -------------------------------------------------------------------------------- 1 | const instanceOf = (left) => (right)=> { 2 | const RP = right.prototype; // 构造函数的原型 3 | while(true) { 4 | if (left === null) { 5 | return false; 6 | } 7 | if (left === RP) { // 一定要严格比较 8 | return true; 9 | } 10 | left = left.__proto__; // 沿着原型链重新赋值 11 | } 12 | } 13 | 14 | console.log(instanceOf("1")(String)) 15 | console.log(instanceOf(1)(String)) 16 | console.log(instanceOf(true)(Boolean)) 17 | console.log(instanceOf([])(Array)) 18 | console.log(instanceOf({})(Object)) 19 | 20 | -------------------------------------------------------------------------------- /富文本编辑器相关知识点/README.md: -------------------------------------------------------------------------------- 1 | # 富文本编辑器相关知识点 2 | 学习比较重要的两个api 3 | 4 | - `getSelection()` 5 | - `execCommand()` 6 | -------------------------------------------------------------------------------- /富文本编辑器相关知识点/replace.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 复制粘贴 会产生 有 style 我们项目游戏端不支持 style 行内样式 3 | * 需要手动替换掉 4 | */ 5 | 6 | const test = ` 7 | 尊:
8 | ` 9 | 10 | const a = test.replace(/<([a-z]+)[^>]*>/igm, "<$1>") 11 | 12 | // console.log(a); 13 | 14 | 15 | //之前 /style="(.*)"/gmi 没把 > 排除 所以只能匹配到一组 16 | const b = test.replace(/style="([^>]*)"/gmi,"") 17 | 18 | console.log(b) 19 | 20 | 21 | //这种也可以 22 | const c = test.replace(/([^>]*)(style="[^>]*")([^>]*)/ig,"$1$3") 23 | 24 | console.log(c); -------------------------------------------------------------------------------- /将blob 转成 file.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 16 | 17 | -------------------------------------------------------------------------------- /异步迭代.js: -------------------------------------------------------------------------------- 1 | const arr = [1,2,3] 2 | 3 | const get = () => new Promise((res)=>{ 4 | setTimeout(()=>{ 5 | res(1) 6 | }) 7 | }) 8 | 9 | const a = arr.map(async (number)=> { 10 | const n = await get() 11 | return number + n 12 | }) 13 | 14 | console.log(a); 15 | 16 | // 异步迭代 17 | 18 | const b = await arr.map(async (number)=> { 19 | const n = await get() 20 | return number + n 21 | }) 22 | 23 | console.log(b); 24 | -------------------------------------------------------------------------------- /手机震动/index.js: -------------------------------------------------------------------------------- 1 | navigator.vibrate(1000) //震动 100ms 2 | 3 | navigator.vibrate([1000, 2000, 500]) // 依次震动 4 | 5 | navigator.vibrate(0) // 暂停震动 -------------------------------------------------------------------------------- /拖拽/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ljk", 3 | "age": 18 4 | } 5 | -------------------------------------------------------------------------------- /捕获Primise 异常.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 24 | 25 | -------------------------------------------------------------------------------- /控制反转/Container.ts: -------------------------------------------------------------------------------- 1 | export class Container { 2 | bindMap = new Map(); 3 | 4 | // 实例的注册 5 | bind(identifier: string, clazz: any, constructorArgs: Array) { 6 | this.bindMap.set(identifier, { 7 | clazz, 8 | constructorArgs 9 | }); 10 | } 11 | 12 | // 实例的获取 13 | get(identifier: string): T { 14 | const target = this.bindMap.get(identifier); 15 | const { clazz, constructorArgs } = target; 16 | const inst = Reflect.construct(clazz, constructorArgs); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /数组的交集和差集.js: -------------------------------------------------------------------------------- 1 | const arr1 = [1, 2, 3] 2 | const arr2 = [3, 4, 5]; 3 | 4 | //数组并集 5 | console.log([...new Set([...arr1, ...arr2])]); 6 | //输出:[1, 2, 3, 4, 5] 7 | 8 | //数组交集 9 | console.log(arr1.filter((v) => new Set(arr2).has(v))); 10 | //输出:[3] 11 | 12 | //数组差集 13 | console.log(arr1.filter((v) => !new Set(arr2).has(v))); 14 | //输出:[1, 2] 15 | console.log(arr2.filter((v) => !new Set(arr1).has(v))); 16 | //输出:[4, 5] 17 | 18 | 19 | //object[] 的 差集 20 | const arr1 = [{a:1},{a:2}] 21 | const arr2 = [{a:1},{a:2},{a:3}] 22 | const result = arr2.filter( 23 | (audio, i) => 24 | arr1.findIndex( 25 | v => v.a === audio.a 26 | ) === -1 27 | ) 28 | // 输出 : [{a:3}] 29 | -------------------------------------------------------------------------------- /旋转木马轮播封装/.idea/.name: -------------------------------------------------------------------------------- 1 | 旋转木马轮播封装 -------------------------------------------------------------------------------- /旋转木马轮播封装/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /旋转木马轮播封装/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /旋转木马轮播封装/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /旋转木马轮播封装/.idea/旋转木马轮播封装.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /旋转木马轮播封装/11.css: -------------------------------------------------------------------------------- 1 | *{ 2 | padding: 0; 3 | margin: 0; 4 | font-family: "Microsoft YaHei"; 5 | } 6 | body{ 7 | padding: 25px; 8 | } 9 | .main{ 10 | width:640px; 11 | height:270px; 12 | margin: 0 auto; 13 | position: relative; 14 | } 15 | .main .lunbo-ul{ 16 | width: 640px; 17 | height:270px; 18 | list-style-type: none; 19 | position: relative; 20 | } 21 | .main .lunbo-ul a,img{ 22 | display: block; 23 | } 24 | img{ 25 | width: 100%; 26 | } 27 | .main .lunbo-ul li{ 28 | width: 640px; 29 | height:270px; 30 | position: absolute; 31 | 32 | } 33 | .btn{ 34 | width: 100px; 35 | height:270px; 36 | position: absolute; 37 | z-index: 99; 38 | top:0; 39 | font-size: 50px; 40 | color:#FFF; 41 | text-align: center; 42 | line-height:270px; 43 | text-shadow: 1px 1px 2px rgba(0,0,0,.31); 44 | cursor: pointer; 45 | background: red; 46 | opacity: .5; 47 | } 48 | .btn-left{ 49 | left:0; 50 | } 51 | .btn-right{ 52 | right:0; 53 | } -------------------------------------------------------------------------------- /旋转木马轮播封装/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/旋转木马轮播封装/images/1.jpg -------------------------------------------------------------------------------- /旋转木马轮播封装/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/旋转木马轮播封装/images/2.jpg -------------------------------------------------------------------------------- /旋转木马轮播封装/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/旋转木马轮播封装/images/3.jpg -------------------------------------------------------------------------------- /旋转木马轮播封装/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/旋转木马轮播封装/images/4.jpg -------------------------------------------------------------------------------- /旋转木马轮播封装/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/旋转木马轮播封装/images/5.jpg -------------------------------------------------------------------------------- /旋转木马轮播封装/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/旋转木马轮播封装/images/6.jpg -------------------------------------------------------------------------------- /旋转木马轮播封装/lunbo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 旋转木马轮播封装练习 6 | 7 | 8 | 9 |
18 |
<
19 |
    20 |
  • 21 |
  • 22 |
  • 23 |
  • 24 |
  • 25 |
26 |
>
27 |
28 | 29 | 30 | 31 | 37 | -------------------------------------------------------------------------------- /是否为URL.js: -------------------------------------------------------------------------------- 1 | function isURL(value) { 2 | return /^((https?):\/\/)[\w-]*(\.[\w-]+|localhost)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?$/.test( 3 | value 4 | ) 5 | } 6 | 7 | console.log(isURL('http://www.baidu.com')) 8 | console.log(isURL('http://www.baidu.com:80')) 9 | console.log(isURL('http://www.baidu.com/v1')) 10 | console.log(isURL('http://www.baidu.com/v1.')) // false 11 | console.log(isURL('http://www.c-c-1.com')) 12 | console.log(isURL('https://www.c-c-1.com')) 13 | console.log(isURL('www.baidu.com')) 14 | console.log(isURL('www.baidu.com/v1')) 15 | console.log('===') 16 | console.log(isURL('http://localhost')) 17 | console.log(isURL('http://localhost:80')) 18 | console.log(isURL('http://localhost/v1')) 19 | console.log(isURL('http://localhost.')) 20 | console.log(isURL('http')) 21 | console.log(isURL('https')) 22 | console.log(isURL('http://')) 23 | console.log(isURL('http://www')) 24 | console.log(isURL('11')) 25 | console.log(isURL(1)) 26 | -------------------------------------------------------------------------------- /标签函数.js: -------------------------------------------------------------------------------- 1 | function log(a,...args) { 2 | console.log(a, args) 3 | console.log(a.raws) 4 | } 5 | 6 | log`你好 ${1} ${2} ${3} 哈哈` 7 | 8 | -------------------------------------------------------------------------------- /标签函数String.raw.js: -------------------------------------------------------------------------------- 1 | const name = 'ljk' 2 | 3 | console.log(String.raw`你好, 我是 ${name}`) // 你好, 我是 ljk 4 | -------------------------------------------------------------------------------- /格式化文件大小/index.js: -------------------------------------------------------------------------------- 1 | const formatFileSize = fileSize => { 2 | const sizeUnitArr = ['Byte', 'KB', 'MB', 'GB']; 3 | if (fileSize == 0) { 4 | return '0 KB'; 5 | } 6 | const i = parseInt(Math.floor(Math.log(fileSize) / Math.log(1024))); 7 | if (i == 0) { 8 | return fileSize + sizeUnitArr[i]; 9 | } 10 | return (fileSize / Math.pow(1024, i)).toFixed(1) + sizeUnitArr[i]; 11 | }; 12 | 13 | 14 | console.log(formatFileSize(1024)); //1.0KB 15 | console.log(formatFileSize(1000)); //1000Byte 16 | console.log(formatFileSize(1024 * 10000)); //9.8MB 17 | 18 | 19 | -------------------------------------------------------------------------------- /检测是否支持css属性.js: -------------------------------------------------------------------------------- 1 | console.log(CSS.supports('display', 'grid')) 2 | -------------------------------------------------------------------------------- /模仿封装/js旋转.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/模仿封装/js旋转.html -------------------------------------------------------------------------------- /模板.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Js实现模板 6 | 11 | 12 | 13 | 14 |
hello! { str11 }
15 | 16 | 36 | -------------------------------------------------------------------------------- /模板解析/parse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {*} template 3 | * @description 模板 {内容} 4 | */ 5 | 6 | const parseTemplate = (template = '') => { 7 | return template 8 | .replace( 9 | /(\{)([^\{]+)(\})/g, 10 | `$1$2$3`, 11 | ) 12 | .replace(/<\/script/g,'<\\/script') 13 | .replace(/ 10 | 36 | 37 | 38 | 39 | 45 | -------------------------------------------------------------------------------- /轮播封装优化版/images/banner1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/轮播封装优化版/images/banner1.jpg -------------------------------------------------------------------------------- /轮播封装优化版/images/banner2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/轮播封装优化版/images/banner2.jpg -------------------------------------------------------------------------------- /轮播封装优化版/images/banner3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/轮播封装优化版/images/banner3.jpg -------------------------------------------------------------------------------- /轮播封装优化版/images/banner4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/轮播封装优化版/images/banner4.jpg -------------------------------------------------------------------------------- /轮播封装优化版/images/banner5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/轮播封装优化版/images/banner5.jpg -------------------------------------------------------------------------------- /轮播封装优化版/images/left-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/轮播封装优化版/images/left-arrow.png -------------------------------------------------------------------------------- /轮播封装优化版/images/right-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijinke666/javascript-demos/fffed884a23f8a250d4b55ba9cdd66d45aa62d76/轮播封装优化版/images/right-arrow.png -------------------------------------------------------------------------------- /输入sb/index.js: -------------------------------------------------------------------------------- 1 | const string = (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]] 2 | 3 | console.log(string); //"sb" 4 | 5 | -------------------------------------------------------------------------------- /迷你redux/compose.js: -------------------------------------------------------------------------------- 1 | function compose(...fns) { 2 | return (...args) => fns.reduce((arg, fn) => fn(arg), ...args) 3 | } 4 | 5 | module.exports = compose 6 | 7 | const fn = compose( 8 | (n) => n + 1, 9 | (n) => n + 2, 10 | (n) => n + 3, 11 | ) 12 | 13 | console.log(fn(4)); 14 | -------------------------------------------------------------------------------- /链式调用/index.js: -------------------------------------------------------------------------------- 1 | class Utils { 2 | constructor(value = 0){ 3 | this.value = value 4 | } 5 | add(...attr){ 6 | const data = [...attr,this.value].reduce((num,v)=> { 7 | num += v 8 | return num 9 | },0) 10 | this.value = data 11 | return this 12 | } 13 | 14 | valueOf(){ 15 | return this.value 16 | } 17 | toString(){ 18 | return this.value.toString() 19 | } 20 | } 21 | 22 | 23 | const u = new Utils(2) 24 | 25 | u.add(1,2,3).add(4).add(5) -------------------------------------------------------------------------------- /闭包/闭包2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 闭包的酸爽 9 | 10 | 11 | 12 | 13 | 14 | 60 | 61 | -------------------------------------------------------------------------------- /闭包/闭包3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |

点击单选框获取当前的value

11 | 1 12 | 2 13 | 3 14 | 15 | 23 | -------------------------------------------------------------------------------- /随机汉字.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |

11 | 12 | 13 | 20 | -------------------------------------------------------------------------------- /随机颜色.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 13 | 14 | 15 | 16 | 17 | 27 | -------------------------------------------------------------------------------- /震动.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 震动 8 | 9 | 10 | 11 | 12 | 13 | 14 | 25 | 26 | -------------------------------------------------------------------------------- /高级/call继承.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | call继承 6 | 7 | 8 | 9 | 10 | 55 | -------------------------------------------------------------------------------- /高级/try-catch语句.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | try-catch语句 6 | 7 | 8 | 9 | 10 | 17 | -------------------------------------------------------------------------------- /高级/函数块级.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 | 18 | -------------------------------------------------------------------------------- /高级/函数,switch ,循环.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 | 51 | -------------------------------------------------------------------------------- /高级/原始表达式.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 原始表达式 6 | 7 | 8 | 9 | 10 | 33 | -------------------------------------------------------------------------------- /高级/在元素创建之前绑定事件.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 19 | 20 | 21 | 28 | 29 | 30 | 31 | 49 | -------------------------------------------------------------------------------- /高级/对象.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 对象 6 | 7 | 8 | 9 | 10 | 37 | -------------------------------------------------------------------------------- /高级/运算符.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 运算符 6 | 7 | 8 | 9 | 10 | 67 | -------------------------------------------------------------------------------- /高级/隐式转换.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 隐式转换 6 | 7 | 8 | 9 | 10 | 19 | --------------------------------------------------------------------------------