_] javascript的表达式“总价钱是”+800+“元”的结果是( )。 a. 一">
赞
踩
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>计时器</title>
- </head>
-
- <body>
- <div id="counter"></div>
- </body>
-
- </html>
- <script>
- /* 选中所需要的couter */
- const ele = document.getElementById('counter');
- /* 定义两个变量 */
- let intervalId, seconds;
- /* 定义一个计算时间的方法 */
- function counter() {
- /* 定义定时器 */
- intervalId = window.setInterval(() => {
- --seconds;
- ele.innerText = seconds;
- if (seconds === 0) {
- alert('计时结束');
- window.clearInterval(intervalId);
- }
- }, 1000);
- }
-
- function stopCounter() {
- window.clearInterval(intervalId);
- }
-
- function resumeCounter() {
- counter();
- }
-
- seconds = 100;
- counter();
- </script>
运行结果
- 1.存储时记录下有效截止时间
- 2.取数据时判断是否超过有效时间,在有效期内则返回,不在则提示或返回空并且将其删除
- class MyStorage {
- get(key) {
- const wrapValue = localStorage.getItem(key)
- if (wrapValue == null) {
- return undefined
- }
-
- const {value, expires} = JSON.parse(wrapValue)
- - if ((expires != null && Date.now() < expires) || expires == null) {
- + if (!expires || Date.now() < expires) {
- return value
- }
- -
- + localStorage.rmeoveItem(key)
- return undefined
- }
-
- set(key, value, period) {
- const wrapValue = { value };
- if (period != null) {
- wrapValue.expires = Date.now() + period;
- }
-
- localStorage.setItem(key, JSON.stringify(wrapValue));
- }
- }
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>商品sku</title>
- </head>
-
- <body>
-
- </body>
-
- </html>
- <script>
- var a = ['黄', '绿']
- var b = ['s', 'l']
- var c = ['大', '小']
-
- function decar(...args) {
- return args.reduce((acc, item) => {
- const res = []
- for (let i = 0; i < acc.length; i++) {
- for (let j = 0; j < item.length; j++) {
- const prev = [].concat(acc[i])
- res.push([...prev, item[j]])
- }
- }
- return res
- })
- }
- decar(a, b, c)
- console.log(decar(a, b, c))
- </script>
运行结果
- undefined是变量已声明,但未赋值
- ReferenceError: xxx is not defined 是xxx未声明,使用了不存在的变量
-
- JavaScript Number.toPrecision() 函数详解
- JavaScript:
-
- numberObject.toPrecision( [ precision ] )
-
- 如果没有提供precision参数或其值为undefined,则将转而调用toString()方法进行处理。
- 如果提供了参数,则参数precision必须介于 [1, 21] 之间,否则将报错。
- 如果数字的有效位数大于precision,将会根据第precision + 1位的有效数字进行四舍五入。
- 返回值
-
- toPrecision()函数的返回值为String类型,返回该数字以指数计数法或定点表示法的表示形式。如果该数字的有效位数小于precision位,则在小数部分填充相应位数的0。
-
- 如果参数precision大于等于数字整数部分的位数,则返回值将采用定点表示法;否则将采用指数计数法。
-
- 有效数字的位数是从数字第一个不为0的数(包括整数部分和小数部分)开始计算的位数。
示例&说明
- JavaScript:
-
- //toPrecision()会进行四舍五入
-
- var num = 423.536;
- // 调用的是toString()方法
- document.writeln( num.toPrecision() ); // 423.536
-
- num = 562345.12456;
- // 由于整数部分有6位,要求只有3位有效数字,必须采用指数计数法才能表示。
- document.writeln( num.toPrecision( 3 ) ); // 5.62e+5
-
- num = -2651.10;
- // 整数部分有4位,要求的有效数字为4位,采用定点表示法
- document.writeln( num.toPrecision( 4 ) ); // -2651
-
- num = 4564561.12457;
- // 整数部分有7位,要求有效数字为1位,采用指数计数法
- document.writeln( num.toPrecision( 1 ) ); // 5e+6
-
- num = 231;
- // 整数部分有3位,要求有效数字为5位,采用定点表示法,并在小数部分填充两个0
- document.writeln( num.toPrecision( 5 ) ); // 231.00
document.documentElement.scrollTop || document.body.scrollTop;
- call 的第一个参数用于改变上下文,由于没有用到 this,第一个参数 Number 实际上没有用。
-
- Number.call(Number, undefined, 0) 等价于 Number(undefined, 0),由于 Number 只会接受第一个参数。
- Number.call.call(Number, undefined, 0) 等价于 Number.call(undefined, 0),也就是 Number(0)。
ReferenceError
指的是引用出错,比如尝试访问未定义的变量,或者提前访问无提升的变量,都会引发这个错误:
- console.log(foo); // ReferenceError: foo is not defined
- let foo = 1;
-
- TypeError
-
指的是类型出错。
众所周知JavaScript是一个弱类型的语言,这既是它的优点,也经常被人诟病。你永远也不知道 a + b 是在做数值加减还是字符串拼接,而且似乎 a + b 几乎从来也不会报错。
而tc39自 ES5 到 ES6 以来,将 TypeError 的频率几乎翻了4倍之多。目的就是为了规范和强调类型这一概念,避免过于模糊类型这一概念导致JavaScript对于语义的不确定性。
- Symbol() + 1; // TypeError: Cannot convert a Symbol value to a number
-
- ({ toString: () =>({}) }) + 'a'; // TypeError: Cannot convert object to primitive value
这样使得JavaScript更为规范,当一个方法的参数需要一个 number 但却收到了一个 object,与其让它返回 NaN,不如果断地抛出 TypeError 吧。
- 如何避免JS浮点运算的精度问题(例:0.1+0.7=0.7999999999999999)
- function precision(num1,num2){
- num1Length = num1.toString().length;
- num2Length = num2.toString().length;
- let len = num1Length > num2Length ? num1Length : num2Length;
- return (num1 + num2).toPrecision(len);
- }
- console.log(precision(0.1,0.7));
JavaScript:
numberObject.toPrecision( [ precision ] )
如果没有提供precision参数或其值为undefined,则将转而调用toString()方法进行处理。
如果提供了参数,则参数precision必须介于 [1, 21] 之间,否则将报错。
如果数字的有效位数大于precision,将会根据第precision + 1位的有效数字进行四舍五入。
返回值
toPrecision()函数的返回值为String类型,返回该数字以指数计数法或定点表示法的表示形式。如果该数字的有效位数小于precision位,则在小数部分填充相应位数的0。
如果参数precision大于等于数字整数部分的位数,则返回值将采用定点表示法;否则将采用指数计数法。
有效数字的位数是从数字第一个不为0的数(包括整数部分和小数部分)开始计算的位数。
示例&说明
- JavaScript:
-
- //toPrecision()会进行四舍五入
-
- var num = 423.536;
- // 调用的是toString()方法
- document.writeln( num.toPrecision() ); // 423.536
-
- num = 562345.12456;
- // 由于整数部分有6位,要求只有3位有效数字,必须采用指数计数法才能表示。
- document.writeln( num.toPrecision( 3 ) ); // 5.62e+5
-
- num = -2651.10;
- // 整数部分有4位,要求的有效数字为4位,采用定点表示法
- document.writeln( num.toPrecision( 4 ) ); // -2651
-
- num = 4564561.12457;
- // 整数部分有7位,要求有效数字为1位,采用指数计数法
- document.writeln( num.toPrecision( 1 ) ); // 5e+6
-
- num = 231;
- // 整数部分有3位,要求有效数字为5位,采用定点表示法,并在小数部分填充两个0
- document.writeln( num.toPrecision( 5 ) ); // 231.00
- 1、(function(){
- //code
- }())
-
- 2、!function(){
- //code
- }()
-
- 3、!(function(){
- //code
- })()
-
- 4、!(()=>{
- //code
- })()
- for of 用于遍历于数组和可迭代对象得到的是entity({key: value}), for in 用于遍历对象的得到的是对象的属性名
- for in 不可用来遍历一个数组, for in 将会把数组中的 length 等不需要的属性给一并遍历出来
- for of 不可用来遍历对象,对象是一个不可迭代对象。
- const isSameArray = function (array) {
- if (Array.isArray(array)) {
- return new Set(array).size === 1;
- }
-
- return false;
- };
- // 方法一 防抖
-
- function debounce(f, ms) {
- let time;
- return function(){
- let arg = Array.prototype.slice.call(arguments, 1);
- if(time) {
- clearTimeout(time);
- }
- time = setTimeout(function(){
- f.apply(this, arg)
- },ms)
- }
- }
-
- // 方法二 节流
- function throttle(f, ms){
- let lastTime = 0;
- return function(){
- let arg = Array.prototype.slice.call(arguments, 1);
- let newTime = Date.now();
- if(newTime-lastTime > ms) {
- setTimeout(function(){
- f.apply(this, arg)
- },ms)
- }
- lastTime = newTime;
- }
- }
-
- 防抖法:在一段时间内重复请求,则取消本次请求
- 节流法:在一段时间内只能请求一次,下次请求必须在前一次请求完成后
- 等值法:未完成请求状态不再请求,而是完成后直接返回相同的内容
start
链表结构是我们在面试中经常会被问起的较为基础的数据结构问题,起初学习数据结构使用的是C++语言,最近在做前端面试题的过程中没碰到了需要用js实现双链表的需求,百度出来的文章发现可很多错误,于是索性自己重新写了,并且列出了一些错误点,这里给大家较为详细的一步步看一下实现思想和步骤,相较于C++语言,js的实现可以说是很简单了,不需要创建繁琐的对象,更加直观易懂;
首先我们来看一下双向链表的结构图:
在这里插入图片描述
每个结点包含三部分,指向前一个结点的指针(pre),指向后一个节点的指针(next),以及自己的数据部分(element),于是我们就可以先写出结点对象function Node:定义结点对象
- function Node(element) {
- this.element = element
- this.next = null
- this.previous = null
- }
然后我们开始实现插入链表的算法
在这里插入图片描述
(声明)下面函数中的this是我们最后初始化链表的实例,这里大家不要疑惑。可以拉到最下面我们初始化链表那里,相信你会明白呦
- **`function insert`:插入节点**
-
- function insert(newelement, currentelement) {
- var newNode = new Node(newelement)
- var currentNode = this.find(currentelement)
- if (currentNode === 'error') {
- console.log('无法插入,要插入节点不存在')
- return
- }
- if (currentNode.next != null) {
- newNode.next = currentNode.next
- currentNode.next = newNode
- newNode.previous = currentNode
- newNode.next.previous = newNode
- } else {
- currentNode.next = newNode
- newNode.previous = currentNode
- }
- }
function find:找到插入位置
- function find(element) {
- var currentNode = this.head
- while (currentNode.element != element) {
- /*如果找到最后一个节点还没有找到我们的插入点,那么我们就会返回错误*/
- if (currentNode.next == null) {
- console.log('can not find this node; maybe not have this node')
- return 'error'
- }
- currentNode = currentNode.next
- }
- return currentNode
- }
接下来是移除结点的实现,如果看懂了插入节点的实现,那么移除就会很简单了,相信大家都可以很快明白,这里就直接贴出实现代码;
- function remove:移除一个结点
-
- function remove(element) {
- var currentNode = this.find(element)
- if (currentNode === 'error') {
- console.log('要移除节点不存在')
- return
- }
- /*首先是不是头尾节点的情况*/
-
- if (currentNode.next != null && currentNode.previous != null) {
- currentNode.previous.next = currentNode.next
- currentNode.next.previous = currentNode.previous
- currentNode.next = null
- currentNode.previous = null
- } else if (currentNode.previous == null) {
- /*当是头节点的时候*/
- this.head = currentNode.next
- currentNode.next.previous = null
- currentNode.next = null
- } else if (currentNode.next == null) {
- /*当是尾节点的时候 */
-
- currentNode.previous.next = null
- currentNode.previous = null
- }
- }
-
截止到这里我们基本功能已经有了,下面使我们根据自己需要可以自定义一些其他函数
- function lastNode:找到最后一个节点
-
- function lastNode() {
- var head = this.head
- while (head.next != null) {
- head = head.next
- }
- return head //这里head在尾节点的位置
- }
- function append:将要添加的结点放在链表末尾
-
- function append(element) {
- var lastnode = this.lastNode()
- var newNode = new Node(element)
- lastnode.next = newNode
- newNode.previous = lastnode
- }
- function showlist:将链表所有的结点打印出来
-
- function showlist() {
- var head = this.head
- do {
- console.log(head.element)
- head = head.next
- } while (head != null)
- // 大家可以看一下下面注释内容存在什么问题,留给大家思考一下
- // while (head.next != null) {
- // console.log(head.element)
- // head = head.next
- // }
- }
接下来是对链表进行初始化,这也是上述函数中所有this所代表的实例
function initlist:初始化链表,并将所有方法注册到链表中
- function initlist() {
- this.head = new Node('one')
- this.find = find
- this.insert = insert
- this.remove = remove
- this.showlist = showlist
- this.lastNode = lastNode
- this.append = append
- }
-
- var list = new initlist()
- list.insert('two', 'one')
- list.insert('four', 'two')
- list.insert('three', 'two')
-
- // console.log(list.head.next)
- list.showlist()
- list.append('A')
- list.append('B')
- list.insert('B2', 'B')
- list.showlist()
- console.log(list.lastNode())
- // list.remove('one')
- // list.showlist()
- console.log(list.find('A').previous)
- // console.log(list.find('four').previous)
- // console.log(list.head.element)
-
下面是运行结果:
在这里插入图片描述
源码:
- function Node(element) {
- this.element = element
- this.next = null
- this.previous = null
- }
- function find(element) {
- var currentNode = this.head
- while (currentNode.element != element) {
- if (currentNode.next == null) {
- console.log('can not find this node; maybe not have this node')
- return 'error'
- }
- currentNode = currentNode.next
- }
- return currentNode
- }
- function insert(newelement, currentelement) {
- var newNode = new Node(newelement)
- var currentNode = this.find(currentelement)
- if (currentNode === 'error') {
- console.log('无法插入,要插入节点不存在')
- return
- }
- if (currentNode.next != null) {
- newNode.next = currentNode.next
- currentNode.next = newNode
- newNode.previous = currentNode
- newNode.next.previous = newNode
- } else {
- currentNode.next = newNode
- newNode.previous = currentNode
- }
- }
- function remove(element) {
- var currentNode = this.find(element)
- if (currentNode === 'error') {
- console.log('要移除节点不存在')
- return
- }
- /*首先是不是头尾节点的情况*/
-
- if (currentNode.next != null && currentNode.previous != null) {
- currentNode.previous.next = currentNode.next
- currentNode.next.previous = currentNode.previous
- currentNode.next = null
- currentNode.previous = null
- } else if (currentNode.previous == null) {
- /*当是头节点的时候*/
- this.head = currentNode.next
- currentNode.next.previous = null
- currentNode.next = null
- } else if (currentNode.next == null) {
- /*当是尾节点的时候 */
-
- currentNode.previous.next = null
- currentNode.previous = null
- }
- }
- function showlist() {
- var head = this.head
- do {
- console.log(head.element)
- head = head.next
- } while (head != null)
- // while (head.next != null) {
- // console.log(head.element)
- // head = head.next
- // }
- }
- function initlist() {
- this.head = new Node('one')
- this.find = find
- this.insert = insert
- this.remove = remove
- this.showlist = showlist
- this.lastNode = lastNode
- this.append = append
- }
- function append(element) {
- var lastnode = this.lastNode()
- var newNode = new Node(element)
- lastnode.next = newNode
- newNode.previous = lastnode
- }
- function lastNode() {
- var head = this.head
- while (head.next != null) {
- head = head.next
- }
- return head
- }
- var list = new initlist()
- list.insert('two', 'one')
- list.insert('four', 'two')
- list.insert('three', 'two')
-
- // console.log(list.head.next)
- list.showlist()
- list.append('A')
- list.append('B')
- list.insert('B2', 'B')
- list.showlist()
- console.log(list.lastNode())
- // list.remove('one')
- // list.showlist()
- console.log(list.find('A').previous)
- // console.log(list.find('four').previous)
- // console.log(list.head.element)
-
END
- ajax只支持http/https协议,
- 可以通过自定义http头来间接支持自定义协议
- const deepClone = (obj) => {
- const copy = obj instance Array ? [] : {};
- for (let key in obj) {
- if (obj.hasOwnProperty(key)) {
- copy[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
- }
- }
- return copy;
- }
- AJAX是发送HTTP请求的一种方式,只不过浏览器给它加了一个同源策略而已。
- 所以从这一点可以得出一个结论:AJAX本质上安全性和HTTP请求一样
pushState + ajax = pjax
- var list = [{
- "orgId": 1,
- "orgName": "校长办公室1",
- "parentId": 0
- },{
- "orgId": 2,
- "orgName": "校长办公室2",
- "parentId": 1,
- },{
- "orgId": 3,
- "orgName": "校长办公室3",
- "parentId": 2,
- }];
-
- function findParent(idx){
- list.forEach(item => {
- if (idx === item['orgId']){
- let pid = item['parentId']
- console.log(pid)
- findParent(pid)
- }
- })
- }
- findParent(3); //2 1 0
-
- var data = {
- count: 1,
- value: 2
- }
- Object.defineProperty(data, 'count', {
- enumerable: true,
- configurable: true,
- get: function () {
- console.log('你访问了count', this.count); // 循环读取data.count 导致报错
- return this.value
- },
- set: function (newVal) {
- console.log('你设置了count');
- }
- })
- console.log(data.count) // 报错 Maximum call stack size exceeded
- function padNumber(n, targetLen, placeholder) {
- const arr = ("" + n).split("");
- const diff = arr.length - targetLen;
- if (diff < 0) {
- return Array(0 - diff)
- .fill(placeholder, 0, 0 - diff + 1)
- .concat(arr)
- .join("");
- } else {
- return arr.join("");
- }
- }
- console.log(padNumber(3458, 8, "0")); //'00003458'
- console.log(padNumber(90990, 3, "-")); //'90990'
- <div id="test"><h5>就是喜欢你</h5></div>
-
- document.getElementById("test").innerHTML //<h5>就是喜欢你</h5> document.getElementById("test").outHTML //<div id="test"><h5>就是喜欢你</h5></div>
- 创建节点
-
- createElement() 创建一个元素节点
- createTextNode() 创建一个文本节点
- createAttribute() 创建一个属性节点
- createComment() 创建一个注释节点
-
- 插入节点
-
- appendChild() 把节点插入到父节点的末尾
- insertBefore() 把节点插入到父节点的某个兄弟节点的前面
-
- 删除节点
-
- removeChild()
-
- 查找节点
-
- getElementById()
- getElementsByTagName()
- getElementsByName()
-
- 替换节点
-
- replaceChild()
-
- function dateToString(date, format = 'yyyy-MM-dd') {
- const d = new Date(date);
- let result = format;
- const _config = {
- 'y+': d.getFullYear(),
- 'M+': d.getMonth() + 1, // 月
- 'd+': d.getDate(), // 日
- 'h+': d.getHours(), // 小时
- 'm+': d.getMinutes(), // 分
- 's+': d.getSeconds(), // 秒
- };
-
- for (const reg in _config) {
- if (!(new RegExp(`(${reg})`).test(result))) continue;
- const match = RegExp.$1;
- let num = `${_config[reg]}`;
- while (num.length < match.length) { num = `0${num}` }
- result = result.replace(match, num);
- }
-
- return result;
- }
-
- function stringToDate(str, format = 'yyyy-MM-dd') {
- let args = [/y+/, /M+/, /d+/, /h+/, /m+/, /s+/];
- args = args.reduce((re, reg, index) => {
- const match = format.match(reg);
- const defaultValue = [1970, 0, 1, 0, 0, 0][index];
- if (!match) return re.concat([defaultValue]);
- var index = match.index;
- const num = Number(str.slice(index).match(/\d+/));
- return re.concat([num]);
- }, []);
- args.unshift(null);
- return new(Date.bind.apply(Date, args));
- }
- pjax 是一个 jQuery 插件,它通过 ajax 和 pushState 技术提供了极速的(无刷新 ajax 加载)浏览体验,并且保持了真实的地址、网页标题,浏览器的后退(前进)按钮也可以正常使用。
- pjax 的工作原理是通过 ajax 从服务器端获取 HTML,在页面中用获取到的 HTML 替换指定容器元素中的内容。然后使用 pushState 技术更新浏览器地址栏中的当前地址。以下两点原因决定了 pjax 会有更快的浏览体验:
- 不存在页面资源(js/css)的重复加载和应用;
- 如果服务器端配置了 pjax,它可以只渲染页面局部内容,从而避免服务器渲染完整布局的额外开销。
需要写出轨迹拖动,进度条,开始,暂停,结束功能。
重试次数、重试时间间隔等
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
-
- <body>
-
- </body>
-
- </html>
- <script>
- Promise.retry = (fun, limit = 5) => {
- return new Promise((resolve, reject) => {
- let __num = 1;
- let __run = () => {
- fun()
- .then(res => {
- resolve(res);
- })
- .catch(err => {
- if (__num++ >= limit) {
- reject(err)
- } else {
- console.log('retry again!!')
- __run()
- }
- })
- }
- __run()
- })
- }
-
- let k = 0
-
- function test() {
- return new Promise((resolve, reject) => {
- if (++k >= 3) {
- resolve(k)
- } else {
- reject('hhh')
- }
- })
- }
-
- Promise.retry(test).then(res => {
- console.log('resolve: ', res)
- }).catch(err => {
- console.log('reject: ', err)
- })
- // retry again!!
- // retry again!!
- // resolve: 3
- </script>
运行结果
- 原理是使用canvas画布。
-
- 在页面加载前 mounted方法里:
-
-
- setTimeout(() => {
-
- this.changeimg();
-
- }, 1000);
-
- changeimg( )方法:
-
- changeimg(){
- var self = this;
- var imgsrcArray = [
- require('../../assets/image/income/background.png'),
- $('#qrcode canvas')[0].toDataURL('image/png')
- ];
- var canvas = document.createElement('canvas');
- var ctx = canvas.getContext('2d');
- canvas.width = 750;
- canvas.height = 1334;
- var imglen = imgsrcArray.length;
- var showContent = '我是'+this.showPhone;
- var drawimg = (function f(n){
- if(n < imglen){
- var img = new Image();
- img.crossOrigin = 'Anonymous'; //解决跨域问题
- img.onload = function(){
- if(n == 0){
- ctx.drawImage(img,0,0,750,1334);
- ctx.font = '30px Adobe Ming Std';
-
- ctx.fillText(showContent,250,800);
- ctx.fillText('文字文字',250,850);
- }else{
- ctx.drawImage(img,250,900,250,250);
- }
- f(n+1);
- }
-
- img.src = imgsrcArray[n];
- }else{
- self.downloadUrl = canvas.toDataURL("image/jpeg");
- self.downloadUrl = self.downloadUrl.replace("data:image/jpeg;base64,", "");
- }
- })(0);
- }
-
- 本例中将一张背景图与二维码图合成一张图片 ,
-
- 二维码的生成也需要在此方法之前。
-
- html:
-
- <img style="width:100%;" :src="'data:image/jpeg;base64,' + downloadUrl" alt="">
- <div style="opacity:0;position:absolute;bottom:0;" id="qrcode"></div>
1.设置responseType为 Blob,2.将Blob保存为文件
- 方法
- 1.在线工具
- 2.webpack
-
- 原理
- 1.删除注释
- 2.变量名方法名字符精减
- // 使用位运算符实现
- function add (a, b) {
- if (a == 0 || b == 0) {
- return a || b;
- }
- while (b != 0) {
- let i = b;
- b = (a & b) << 1;
- a = a ^ i;
- }
- return a;
- };
- document.queryNode = function(node){
- if(node.id){
- return '#'+ node.id;
- }
- if(node.className){
- return '.'+ node.id;
- }
- return node.nodeName;
- };
-
- obj.proto === class.prototype 可以递归去找
- obj instanceof class
在微前端有用到js沙箱,例如qiankun框架,主应用的js运行和子任务的js运行不会相互影响,是使用es6的proxy来实现的
- 函数式编程是一种编程思想,纯函数是这种思想的基本
-
- 要实现函数式编程,我们所封装的方法应该是抽象的,应该是和外部状态无关系的,也就需要是纯函数的,这样才能保证抽象的方法可复用而且输出结果只决定于输入参数。
- 在此之前要先了解什么是纯函数,简单来说纯函数的定义有两个:
- 1.返回的结果只依赖于传入的参数。
- 2.执行过程中不产生副作用。
- 在这里就需要了解到什么是副作用
- 1.改变了外部变量或者对象属性
- 2.触发任何外部进程
- 3.发送http请求
- 4.调用其他有副作用的函数
- 5.……
- 那么我们为什么要用纯函数呢,从定义来看,我们可以知道纯函数不管你在什么时候请求它,只要参数是一样的,那返回的结果就肯定是一样的。
- 然后对于副作用我的理解是一个函数的功能要单一 ,你不能即在负责计算或者什么别的行为的同时还负责http请求什么的,发起http请求应该让另外一个函数去单独实现。
- 然后另外一个函数虽然产生了副作用,但是它的返回结果只依赖于传入的参数(比如链接)。这样做的好处有方便测试和后期维护,如何你一个函数负责多个功能,那后面估计看着这个函数都很难受。
- /**
- * 裁切图片
- * @param imgUrl 原始图片路径
- * @param x,y,width,height 从点[x, y]开始,将宽度width,高度height的区域裁切下来
- * tips:需要运行于服务器环境下切图片为同域
- */
- function clipImage(imgUrl, x, y, width, height) {
- return new Promise((resolve, reject) => {
- let cvs = document.createElement("canvas");
- cvs.width = width;
- cvs.height = height;
-
- var ctx = cvs.getContext('2d');
- let _img = new Image();
- _img.src = imgUrl;
- _img.onload = () => {
- ctx.drawImage(_img, 0 - x, 0 - y);
- resolve(cvs.toDataURL());
- }
- })
- }
-
- clipImage("./img/loginbg.jpg", 100, 100, 300, 400).then(res => {
- let __img = document.createElement("img");
- __img.src = res;
- document.body.appendChild(__img);
- })
- Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版规范。因此,使用 for-in 语句遍历对象属性时遍历顺序并非属性构建顺序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是较老的 ECMA-262 第三版规范,属性遍历顺序由属性构建的顺序决定。
-
- 如果我们需要按照一定的顺序输出属性,也可以先在一个数组中保存所有的key值,再将数组排序,最后循环这个key数组,通过key获取对象中的属性即可:
- var user = {};
- if(!user['Jason']) {
- user['Jason'] = [];
- }
- user['Jason']['grade'] = 3;
- user['Jason']['level'] = 1;
-
- if(!user['arthinking']) {
- user['arthinking'] = [];
- }
- user['arthinking']['grade'] = 4;
- user['arthinking']['level'] = 1;
-
- console.log(user);
-
- for(var key in user){
- console.log('key: ', key);
- }
-
- var keys = [];
- for(var key in user){
- keys.push(key);
- }
- keys = keys.sort();
-
- for(var i=0; i<keys.length; i++){
- var key = keys[i];
- console.log(user[key]['grade']);
- }
- (function() {
- var arrDPI = new Array();
- if ( window.screen.deviceXDPI) {
- arrDPI[0] = window.screen.deviceXDPI;
- arrDPI[1] = window.screen.deviceYDPI;
- }
- else {
- var tmpNode = document.createElement( "DIV" );
- tmpNode.style.cssText = "width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden";
- document.body.appendChild( tmpNode );
- arrDPI[0] = parseInt( tmpNode.offsetWidth );
- arrDPI[1] = parseInt( tmpNode.offsetHeight );
- tmpNode.parentNode.removeChild( tmpNode );
- }
- console.dir(arrDPI);
- return arrDPI;
- })()
promise构造函数是同步执行的,then方法是异步执行的。
- 内存泄露:用动态储存分配函数内存空间,在使用完毕后未释放,导致一直占据该内存单元,直到程序结束。
-
- 内存溢出:不顾堆栈分配的局部数据块大小,向数据块中写入过多数据,导致数据越界,结果覆盖了别的数据。常在递归中发生。
- function c(a) {
- return a.replace(/^(\d+)(?:.(\d+))*eE(\d+)/,(_,a,a1,p,n)=>{
- a1=a1||''
- if(p==='-'&&n>0) {
- return '0.'+'0'.repeat(n-1)+a+a1
- }else{
- return a+(a1.length>n? a1.substr(0, n)+'.'+a1.substr(n): a1+'0'.repeat(n-a1.length))
- }
- })
- }
- <body>
- <input type="text" id="amount">
- <em id="message"></em>
- </body>
- <script>
- const amountInput = document.getElementById('amount');
- const msg = document.querySelector('#message');
- amountInput.oninput = function (event) {
- let value = event.target.value;
- let pat = /^\d+(\.\d{1,2})?$/;
- msg.innerHTML = pat.test(value) ? 'True' : 'False';
- }
- </script>
-
- 更优方式---input的 pattern属性
-
- <input type="text" pattern="^\d+(\.\d{1,2})?$">
- 使用delete删除数组元素,其长度会改变吗?
-
-
-
- 咱来写个案例声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/391932推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。