ES6高级技巧(四)
238
数字->二进制->补码->十进制
const bitwise = N => {
if (N < 2) {
return N == 0 ? 1 : 0
}
/*转化为二进制*/
let str = N.toString(2)
/*补码*/
let sb = ''
for (let i = 0; i < str.length; i++) {
sb += str.charAt(i) == '0' ? '1' : '0'
}
/*转化十进制*/
return parseInt(+sb, 2)
}
console.log(bitwise(10))
some
some的实现逻辑本身就是短路的,一旦返回true后续迭代就不再执行了
let arr = [1, 2, 3, 4, 5]
let sum = ''
arr.some(v=>{
sum+=v
if (v == 3) {
return true
}
})
console.log(sum)
如果continue和break同时存在
let arr = [1, 2, 3, 4, 5]
let text = ''
for (let v of arr) {
if (v === 2) {
continue
}
if (v === 4) {
break
}
text += v + ','
}
console.log(text) // "1,3,"
只用some处理
arr.some(val => {
if (val == 2) {
return //跳过
}
if (val == 4) {
return true
}
sum += val
})
console.log(sum)
判断undefined
const isUndefined = value => value == void 0
let a;
console.log(isUndefined(a)) //true
合并对象
const isObject = value => toString(value) === '[object Object]'
const merage = (a, b) => {
for (let item in b) {
if (isObject(b[item])) {
a[item]=merage(a[item],b[item])
}else{
a[item]=b[item]
}
}
return a
}
去重value
const uniqueBy = (arr, fn) => {
return arr.filter((val, index, array) => {
return array.findIndex(item =>
typeof (fn) == 'function' ? fn.call(this, item) == fn.call(this, val)
: val[fn] == item[fn])
== index
})
}
递归逆序
const fun = num => {
let num1=num/10
let num2=num%10
if (!Math.floor(num1)) {
return num
}
if (Math.floor(num1)) {
return `${num2}`+fun(Math.floor(num1))
}
}
console.log(fun('12345'))
//不用递归,不用api
const fun = num => {
let end=num.length-1
let sum=''
while (end>=0) {
sum+=num[end]
end--
}
return sum
}
console.log(fun('12345'))
深度克隆
const isObject=obj=>Object.prototype.toString.call(obj) === '[object Object]'
const deepClone = (obj) => {
//基础数据类型是值传递
let arr = ['string', 'number', 'boolean', 'undefined']
if (arr.some(val => typeof obj == val)) {
return obj
}
//数组
let cobj;
if (Array.isArray(obj)) {
cobj = obj.map(val => deepClone(val))
}else{
if (isObject(obj)) {
let ret={};
for (let item in obj) {
ret[item]=deepClone(obj[item])
}
return ret
}
}
return cobj
}
console.log(deepClone({a:1,b:{a:1},c:3}))
禁止右键,选择,复制
// 鼠标右键事件 选择 复制
['contextmenu', 'selectstart', 'copy'].forEach(function (ev) {
document.addEventListener(ev, function (event) {
return event.preventDefault()
})
})
//event.preventDefault() 阻止默认的点击事件执行
判断是不是引用数据类型的数据
function isObject(value) {
let type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
数据结构和算法是什么
数据结构是值一组数据的存储结构
算法就是操作数据的方法
数据结构和算法是相辅相成的,数据结构是为服务的,而算法要作用在特定的数据结构上
递归
//阶乘
const fact = n => {
if (n == 1) {
return n
}
return fact(n - 1) * n
}
console.log(fact(5))
//最大公约数
const gcd = (a, b) => {
if (b == 0) return a
return gcd(b, a % b)
}
console.log(gcd(5, 10))
// 走楼梯(一个台阶总共有n级台阶,如果一次可以跳1,2,
//问有多少种可能
const solve=n=>{
if(n==1) return 1
if(n==2) return 2
return solve(n - 1) + solve(n - 2)
}
console.log(solve(2))
//归并排序
const mergeSort = array => {
if (array.length < 2) return array
let mid = Math.floor(array.length / 2)
let left = array.slice(0, mid)
let right = array.slice(mid)
return merge(mergeSort(left), mergeSort(right))
}
const merge = (left, right) => {
let result = []
while (left.length > 0 && right.length > 0) {
if (left[0] < right[0]) {
result.push(left[0])
} else {
result.push(right[0])
}
}
return result.concat(left).concat(right)
}
852 山脉数组的峰顶索引
const pack=array=>{
let i=0
while (i < array.length - 1) {
if (array[i] > array[i+1]) {
return i
}
i++
}
return -1
}
console.log(pack([1, 8, 10, 4]))
Proxy
用于修改某些操作的默认行为,(拦截)(代理)
const proxy=new Proxy(target,hanler)// target 表示拦截的对象,handler 是用来定制拦截行为的对象
let a = {
name: 'zhangsan',
age: 12
}
let proxy = new Proxy(a, {
//拦截读取的属性
get: (target, prop) => 35
})
console.log(proxy.name)
//35
handler没有设置,等同于直接通向源对象
let proxy1 = new Proxy(a, {})
proxy1.a='b'
console.log(a)
//{ name: 'zhangsan', age: 12, a: 'b' }
Proxy实例的方法
get方法
接受三个参数:目标对象,属性名,proxy实例本身
let preson={
name:'zhangsan'
}
let proxy=new Proxy(preson,{
get:(target,props,p)=>{
if (props in target) {
return target[props]
}else{
return ('哥哥报错了')
}
}
})
//如果没有拦截,访问不存在的属性,只会返回undefined
console.log(proxy.aaa)
//get方法可以继承
let p1=Object.create(proxy)
console.log(p1.aaa)
//get拦截,实现数组读取负数索引
const createArray = (...array) => {
let target = []
target.push(...array)
return new Proxy(target, {
get: (target, prop) => {
if (Number(prop) < 0) {
prop = String(target.length + Number(prop))
}
return Reflect.get(target,prop,p)
}
})
}
let p = createArray('a', 'n', 'b')
console.log(p[-2]) //n
set方法
接受四个参数,依次为目标对象,属性名,属性值,proxy实例本身
//设置一个对象不大于200且必须为整数
let preon=new Proxy({},{
set(target,prop,value){
if(prop=='age'){
if (value > 200||typeof(value)!='number') {
throw new Error('报错了')
}
}
}
})
preon.age='a'
console.log(p)
Reflect
Reflect 对象的方法与Proxy对象的方法一一对应
Reflect.get(target,props,args)参数是(目标对象,属性,源对象)let myObjer={
foo:1,
bar:2,
get baz(){//get 函数的时候,会直接执行这个函数
return this.foo+this.bar
}
}
console.log(Reflect.get(myObjer, 'foo'))//1
//改变this的指向从而改变这个值(源对象是用来改变this指向的)
let a = {
foo: 3,
bar: 4
}
console.log(Reflect.get(myObjer, 'baz', a))// 7
Reflect.set(target,prop,vlaue,args) 参数
目标对象,键,值,源对象var myObject = {
foo: 1,
set bar(value) {
return this.foo = value
},
set(value) {
return this.foo = value
}
}
console.log(myObject.foo)//1
//原生方法
myObject.set(3)
console.log(myObject.foo)//3
//Reflect.set
Reflect.set(myObject, 'bar', 2)
console.log(myObject.foo)//2
//改变this指向
//给属性设置赋值函数,则把赋值函数的this绑定给源对象(a)
let a = {
foo: 100//函数执行后,也就是this.foo=2
}
Reflect.set(myObject, 'bar', 2, a)
console.log(a.foo)//2
Reflect.has(target,prop)
Reflect.has 方法对应
prop in objlet myObject={
foo:1
}
//原生
console.log('foo' in myObject)
//新写法
console.log(Reflect.has(myObject, 'foo'))
//第一个参数不是对象会报错
Reflect.deleteProperty(target,prop)
等同于
delete target[prop]用于删除对象的属性,如果target不是对象会报错let myObject={
foo:1
}
//就写法
delete myObject.foo
Reflect.deleteProperty(myObject,'foo')
console.log(myObject)
Reflect.construct(target,args)
等同于new,如果target不是函数会报错
function Greeting(name) {
this.name=name
}
const a=new Greeting('zhangsan')
console.log(a.name)
//new的另一种写法
const b=Reflect.construct(Greeting,['zhangsan'])
console.log(b.name)Reflect.getprototypeOf(target)
Reflect.getPrototypeOf方法用于读取对象的__proto__属性function Greeting(name) {
this.name=name
} const a=new Greeting('zhangsan')
console.log(Object.getPrototypeOf(a) == Greeting.prototype)
//新写法
console.log(Reflect.getPrototypeOf(a) == Greeting.prototype)
两个的区别
Reflect.getPrototypeOf如果不是对象会报错
Object.getPrototypeOf会把这个参数转为对象,然后再运行Reflect.setPrototypeOf(obj,newProto)
设置目标对象的原型
对应
Object.setPrototypeOf(obj,newProto),他返回一个布尔值,表示是否设置成功const myObj = {};
//原生
Object.setPrototypeOf(myObj,Array.prototype)
//新写法
Reflect.setPrototypeOf(myObj,Array.prototype)
console.log(myObj.length)//0
Reflect.apply(func,thisArg,args)
等同于
Function.prototype.apply.call()const array = [1, 2, 3, 4, 4, 5]
console.log(Math.max.apply(undefined,array)) //5
console.log(Math.max.apply(null,array)) //5
console.log(Object.prototype.toString.call([]))
//[object Array]
console.log(Reflect.apply(Math.min,undefined, array))
console.log(Reflect.apply(Object.prototype.toString,null, array))
Reflect.defineProperty(target,prop,attributes)
等同于
Object.definePropertyfunction MyDate(){ }
Object.defineProperty(MyDate,'num',{
value:()=>Date.now()
})
console.log(MyDate.num()) Reflect.defineProperty(MyDate,'now',{
value:()=>Date.now()
})
console.log(MyDate.now())
如果第一个参数不是对象,会报错
Reflect.getOwnPropertyDescriptor(target,prop)
用于得到指定属性的描述对象
let myObject={
name:'zhangsan'
}
//用于得到指定属性的描述对象
console.log(Object.getOwnPropertyDescriptor(myObject, 'name'))
/*{ value: 'zhangsan',
writable: true,
enumerable: true,
configurable: true }*/
//Reflect
console.log(Reflect.getOwnPropertyDescriptor(myObject, 'name'))
Reflect.isExtensible(target)
方法等同于
Object.isExtensible返回一个布尔值,表示当前对象是否扩展Reflect.ownKeys(target)
返回对象的所有属性
let a={
foo:1,
bar:2
}
Reflect.ownKeys(a)
前端开发规范
命名规范
- 目录命名
vue的项目,组件目录名,使用大驼峰命名
leftBarJS,css,html文件命名:使用下划线
account_model.js
- HTML规范
属性上使用双引号
属性民全小写,用中划线(-)做分割符
不要再自动闭合标签结尾处使用斜线
<br>
数组方法

二分搜索
通过值查索引
const binarySearch = (arr, val, start = 0, end = arr.length - 1) => {
if (start > end) return -1;
const mid = Math.floor((end - start) / 2)
if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1)
if (arr[mid] < val) return binarySearch(arr, val, start + 1, mid)
return mid
}
console.log(binarySearch([1, 3, 4, 4, 5, 6, 7, 8, 9, 12], 3))
算字符串的重复次数
算a,b,c,总共重复了多少次
const countStr = str => str.match(/[abc]/gi).length
console.log(countStr('abcabsssabc'))
求length=7的斐波那契的数组
const fibonacciUntilNum = num => {
return Array.from({ length: num })
.reduce(
(acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []
)
}
console.log(fibonacciUntilNum(10))
//[ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
判断是不是Armstrong数
// a*a*a+b*b*b+c*c*c=abc 求出所有的这三个数,也叫Armstrong数
const isArmstrongNumber = digits => {
return (
arr => arr.reduce((acc, val) => acc + Number(val) ** arr.length, 0) == digits
)
(String(digits).split(''))
}
console.log(isArmstrongNumber(1634))
对象解构求值
const state = {
B: 2,
C: 1
};
const reducer3 = (state, payload) => {
return ({
...state,
B:state.B+payload,
C:state.C*payload
})
}
console.log(reducer3(state, 3))
!~
!~[1, 2, 3, 4, 5,].indexOf(8) //true
不存在就为true
其实可以用some
console.log(![1, 2, 3, 4, 5,].some(val => val == 9))
不调换顺序判断,第二个字符串字段是否包含第一个字符串的字段
const isStr = (target, str) => {
return [...str].reduce((acc, val) =>
val == (target[acc] || '') ? acc + 1 : acc
, 0) == target.length
}
console.log(isStr('ca', 'abc'))//false
console.log(isStr('ac', 'abc'))//true
查看原型是什么类型
const getType = v =>
[,null].some(val => val == v)
?v
:v.constructor.name.toLowerCase()
ES6高级技巧(四)的更多相关文章
- React与ES6(四)ES6如何处理React mixins
React与ES6系列: React与ES6(一)开篇介绍 React和ES6(二)ES6的类和ES7的property initializer React与ES6(三)ES6类和方法绑定 React ...
- 深入浅出ES6(四):模板字符串
作者 Jason Orendorff github主页 https://github.com/jorendorff 反撇号(`)基础知识 ES6引入了一种新型的字符串字面量语法,我们称之为模板字符 ...
- 从零开始学 Web 之 ES6(四)ES6基础语法二
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- 用vue.js学习es6(四):Symbol类型
一.Symbol类型: 1.ES6引入了一种新的原始数据类型Symbol,表示独一无二的值.它是JavaScript语言的第七种数据类型,前六种是:Undefined.Null. 布尔值(Boolea ...
- JavaScript学习笔记--ES6学习(四) 字符串的扩展
ES6对字符串进行了一些扩展,主要表现在对Unicode 大于\uFFFF的字符的处理上. 1. ES6中字符的Unicode表示方法 在ES5中,字符串的Unicode表示方法: \uxxxx . ...
- es6 学习四 数组的学习
1. Array.from() 语法: Array.from(arrayLike[, mapFn[, thisArg]]) arrayLike 类数组对象 mapFn 如果指定了该参数,新数组中的每个 ...
- ES6入门四:对象字面量扩展与字符串模板字面量
简洁属性与简洁方法 计算属性名与[[prototype]] super对象(暂时保留解析) 模板字面量(模板字符串) 一.简洁属性与简洁方法 ES6中为了不断优化代码,减低代码的耦合度在语法上下了很大 ...
- es6(四):Symbol,Set,Map
1.Symbol: Symbol中文意思"象征" Symbol:这是一种新的原始类型的值,表示独一无二的值(可以保证不与其它属性名冲突) Symbol()函数前面不能使用new,因 ...
- ES6高级技巧(五)
Set 由于Set结构没有键名,只有键值所有keys方法和values方法的行为完全一致 let a=new Set([1,2,3,4]) //a.keys() a.values() 或者直接用of遍 ...
随机推荐
- python3模块
一.sys模块 import sys #print(sys.path) #打印环境变量 #print(sys.argv) print(sys.argv[3]) Sys.argv[ ]其实就是一个列表, ...
- PHP-FPM Fastcgi 未授权访问漏洞
漏洞原理 Fastcgi Fastcgi是一个通信协议,和HTTP协议一样,都是进行数据交换的一个通道.HTTP协议是浏览器和服务器中间件进行数据交换的协议,浏览器将HTTP头和HTTP体用某个规则组 ...
- SQL Server 两条数据创建时自动关联
begin ),(, ))) from workplan a join org_employee b on b.id = a.idowner , LEN(aa.sglzbbh))) glh from ...
- Django Windows+IIS+wfastcgi 环境下部署
教程基于 Windows 10专业版 + Python3.6 + IIS + wfastcgi 之上部署Django2.2的,同样适用于Windows server2012服务器和Windows7及以 ...
- linux 通过wol远程开机【转】
转自:http://yangbajing.blog.chinaunix.net/uid-10480699-id-5179860.html 今天发现个可以对linux服务器进行远程开机的软件-wakeo ...
- LearnOpenGL.PBR.光照
光源辐射率: 辐射率(radiance)表示光源在给定立体角ω下的辐射通量(或光源发射的能量). 那么假设立体角ω无限小时,辐射率就表示单束光线(或说某个单一方向)的辐射通量. 点光 ...
- 使用rider做为unity的代码编辑器
使用Rider做的编写Unity代码的IDE,记录一些与VS不相同的笔记 安装和设置方法: 我使用Rider 2019.1 + Unity3D 2018.3.4,在安装完Rider之后,在Unity中 ...
- Rust的Drop Trait,相当于析构代码
退出前自动执行的代码. struct CustomSmartPointer { data: String, } impl Drop for CustomSmartPointer { fn drop(& ...
- nullptr与NULL
NULL NULL can be defined as any null pointer constant. Thus existing code can retain definitions of ...
- 题解:[ZJOI2014]璀灿光华
原题链接 OJ 题号 洛谷 3342 loj 2203 bzoj 3619 题目描述 金先生有一个女朋友没名字.她勤劳勇敢.智慧善良.金先生很喜欢她.为此,金先生用\(a^3\)块\(1 \times ...