es6常用点记录

  • let
  • const
  • 解构赋值
  • 字符串
  • 数组
  • 函数
  • 对象
  • Symbol
  • Set
  • WeakSet
  • Map
  • WeakMap
  • Proxy
  • reflect
  • Proxy与Reflex结合实例
  • class
  • promise
  • iterator
  • Gernerator
  • Decorators
  • 模块
  • 学习资料

let

      /* let 声明变量 *//* es6相对于es5的全局和局部作用域,多了一个块作用域,块作用域里声明的变量声明周期只在本块内 */let a = 1;console.info(a); // 输出1for (let i=1;i<10;i++) {console.info(i); // 在块内是可以正常使用的}console.info(i); // 异常,ReferenceError: i is not defined// let是不能重复定义的

const

      /* const 声明常量*//* const也是块作用域的 */const PI = 3.14159265const constObj = {key1: 'value1',key2: 'value2'}console.info(PI); // 输出3.14159265console.info(constObj) // 输出Object { key1: "value1", key2: "value2" }PI = 1 // 错误的,只读,不能修改constObj = {key3: 'value3'} // 错误的,只读,不能修改constObj.key1 = 1 // 可以修改,并不是因为常量可以修改,而是因为对象是引用类型的,这里只是修改对象的值,并没有修改对象的引用console.info(constObj) // 输出Object { key1: 1, key2: "value2" }

解构赋值

      /* 解构赋值 *//* 左边一个结构,右边一个结构,左边与右边解开结构一一赋值 *//* 变量交换、方法返回数组中存有多个变量、 只提取数组中的某些值、重组数组等场景*/// 数组解构赋值let a,b,c;[a,b,c] = [1,2,3];console.info(a); //输出1console.info(b); //输出2console.info(c); //输出3[a,b,c =4] = [1,2];console.info(a); //输出1console.info(b); //输出2console.info(c); //输出4,如果没有默认值,匹配不上,就是undefinedlet d,e,f;[d,e,...f] = [1,2,3,4,5,6,7,8,9,10];console.info(d); //输出1console.info(e); //输出2console.info(f); //Array [ 3, 4, 5, 6, 7, 8, 9, 10 ]// 对象解构let obj1,obj2;({obj1,obj2} = {obj1: 'val1', obj2: 'val2'});console.log(obj1); //输出val1console.log(obj2); //输出val2

字符串

  • 字符串unicode扩展
      /* 字符串unicode扩展 */// \u表示后面是要输出一个unicoide编码对应的字符let unicoideStr1 = '\u0061'let unicoideStr2 = '\u20334'//第一个正常输出是因为在二字节范围内的编码(0x0000-0xffff),第二个已经超过了两个字节的unicode编码表,会把前四位当成一个字符,最后一位当成一个字符console.info(unicoideStr1,unicoideStr2) // a ″4//显示两个字节以上的unicode编码,需要把编码用{}包起来let unicoideStr3 = '\u{20334}'console.info(unicoideStr1,unicoideStr3) // a ?let spacStr = '?'// es5中把超过两个字节长度编码的字符处理为4个字节,就是两个字符,输出2console.info(spacStr.length) //输出2let spacStrTest = '?a'console.info(spacStrTest.length); //输出3console.info("第一个字符",spacStr.charAt(0)) //输出 第一个字符 乱码console.info("第二个字符",spacStr.charAt(1)) //输出 第一个字符 乱码console.info("第二个字符编码",spacStr.charCodeAt(0)) //第一个字符编码 55360console.info("第二个字符编码",spacStr.charCodeAt(1)) //第二个字符编码 57140// 显然,这不是想要的结果,因此es5中处理这种字符是不正确的console.info(spacStrTest.codePointAt(0)) //输出 131892console.info(spacStrTest.codePointAt(0).toString(16)) //输出 20334console.info(spacStrTest.codePointAt(1)) //输出 57140console.info(spacStrTest.codePointAt(2)) //输出 97//es5中根据编码取字符,大于两个字节的不能正常显示console.info(String.fromCharCode('0x20334')) //输出乱码//es6中根据编码取字符
//      console.info(String.fromCodePoint('0x20334')) //输出 ?//es5的循环不能正确取值for(var i=0;i<spacStrTest.length;i++){console.info(spacStrTest[i]); //输出两个乱码和一个a}//es6的循环可以正确取值
//      for(let char of spacStrTest){
//        console.info(char); //输出 ? a
//      }
  • 字符串其他扩展
 /* 字符串其他扩展 */let otherStrTest = 'string'//是否包含console.info(otherStrTest.includes('in')) //输出true//是否起始console.info(otherStrTest.startsWith('str')) //输出true//是否结尾console.info(otherStrTest.endsWith('ing')) //输出true//复制10次console.info(otherStrTest.repeat(10)) //输出stringstringstringstringstringstringstringstringstringstring (一共10次)//字符串模板let name = 'thatway'let age = '18'let man = `name is ${name},age is ${age}`console.info(man) //输出name is thatway,age is 18//padStart、padEnd 接收两个参数,第一个参数是长度,不够就补白,第二个是补白用的字符let simpleStr = '1'let leftPaddingStr = simpleStr.padStart(2,'0')let rightpaddingStr = simpleStr.padEnd(2,'0')console.info(leftPaddingStr, rightpaddingStr) //输出01 10// raw会ie所有字符转义,就是在特殊字符钱加一个\,使其正常输出console.info(String.raw('hello\nworld')) // 输出hello\nworldconsole.info('hello\nworld')// 输出hello//world

数组

   /* 数组 */
//      let arrTest1 = Array.of(1,2,3,4,5)
//      console.info(arrTest1) //输出[1,2,3,4,5]//      let arr = [1,2,3,4,5]
//      let arrTest2 = Array.from(arr)
//      console.info(arrTest2) //输出[1,2,3,4,5]
//      let arrTest3 = Array.from(arr,function(item){return item*2})
//      console.info(arrTest3) //输出[2,3,6,8,10]//fill,把数组中元素全部替换掉let arrFill1 = [1,2,3]console.info(arrFill1.fill(0)) //输出[0,0,0]//fill,把数组中元素从第1个开始替换到第3个let arrFill2 = [1,2,3,4,5]console.info(arrFill2.fill(0,1,3)) //输出[ 1, 0, 0, 4, 5 ]//遍历
//      for(let [index,value] of ['1','2','3'].entries()){
//          console.info(index,value)
//      }//find,查找元素,注意,只返回第一个符合的let arrTest3 = [1,2,3,4,5]console.info(arrTest3.find(function(item){return item > 3})) //输出4console.info(arrTest3.findIndex(function(item){return item > 3})) //输出3//是否包含某个值let arrTest4 = [1,2,3,4,5,NaN]console.info(arrTest4.includes(3)) // 输出trueconsole.info(arrTest4.includes(NaN)) // 输出true

函数

     /* 函数 *///参数默认值function test1(x,y='123'){console.info(x,y);}test1('abc') // 输出abc 123test1('abc','def') // 输出abc def//作用域let x = 'abc'function test2(x,y=x){console.info(x,y)}test2('123') //输出123 123test2() //输出 undefined undefinedfunction test3(z,y=x){console.info(z,y)}test3('123') //输出123 abctest3() //输出 123 undefined//rest参数,参数不确定个数,如果生命了rest参数,不能再声明其他参数了function test4(...params){console.info(params)}test4(1,2,3,4,5) //Array [ 1, 2, 3, 4, 5 ]test4(1) //Array [ 1 ]test4() //[]// ...数组 可以把数组里的值拆散成值console.info(...[1,2,3,4,5]) //1 2 3 4 5console.info('a',...[1,2,3,4,5])//a 1 2 3 4 5//箭头函数//es5的函数声明function arrow5(){console.info('arrow')}//es6的函数声明//方法体只有一行的时候可以不写{}let arrow6 = ()=>console.info('arrow')arrow5() //arrowarrow6() //arrowlet arrowTest = (x,y)=>{console.info(x)console.info(y)}arrowTest(1,2) //1 2//--//伪调用,优化嵌套、依赖函数,可提高性能let fun1 = (x)=>{console.info('fun1')}let fun2 = (x)=>{return fun1(x)}console.info(fun2('abc'))

对象

   /* 对象 */let name= "thatway"let age= 18//es5的对象写法let man5 = {name:name,age:age}//es6中可以将属性名与变量名相同的简写成一个let man6 = {name,age}//结果是一样的console.info(man5,man6);//es5对象中的方法写法let man5_method = {play: function(){console.info("玩")}}//es6对象中的方法写法let man6_method = {play(){console.info("玩")}}//--//      let param = 'sex'
//      //属性表达式
//      let man5_obj = {
//        name: 'thatway',
//        age: 18
//      }
//
//      //es6属性名可以用变量
//      let man6_obj = {
//        name: 'thatway',
//        age: 18,
//        [param]: 'boy'
//      }
//      console.info(man5_obj,man6_obj)//      //比较两个对象是否是同一个,等同于===,注意引用类型的比较
//      console.info(Object.is('abc','abc'))

Symbol

声明不想等的两个值,保证唯一性,babel不支持此API的编译,略过了,知道有这么回事先

Set

      /* set */let list1 = new Set()list1.add("1");list1.add("2");console.info(list.size) //2let arr = [1,2,3,4,5]let list2 = new Set(arr)console.info(list2.size) //5let list3 = new Set()list3.add(1)list3.add(2)list3.add(1)//set中的值必须唯一,因此忽略第二个2,可以利用这个特性来去重//去重的时候不会做类型的转换,比如1'1'是可以同时存在的console.info(list3.size) //2//setadd、has、delete、clear几个方法list3.has(1) //是否含有某个元素list3.delete(1) //删除1 返回true代表成功list3.clear() //清空//遍历for(let key of list3.keys()){console.info(key)}for(let value of list3.values()){console.info(value)}for(let [key,value] of list3.entries()){console.info(key,value)}list3.forEach(function(item){console.info(item)})//在webpack里为什么编译不通过呢,总觉得应该是配置的问题,有空查一下//补充,这个问题是因为babel只转换es6的句法,不转换新的API...比如比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,解决这个问题的办法是引入babel-polyfill,它提供了es6语法的兼容。$ npm install --save babel-polyfill

WeakSet

//WeakSet 和Set的区别是只能放对象,WeakSet是弱引用类型,可以防止内存泄露,其中的对象不存在引用时会被垃圾回收释放内存//WeakSet 没有size属性 只有三个方法add、delete、haslet list_w = new WeakSet();let obj = {title : '111'}list_w.add(obj)//异常,TypeError: [object WeakSet] is not iterable!//WeakSet不支持遍历
//      for(let item of list_w){
//        console.info(item)
//      }//异常,TypeError: WeakSet value must be an object, got the number 1list_w.add(1)

Map

 //map//map里放的是键值对,键可以是任何类型let mapTest1 = new Map()mapTest1.set("key","value")console.info(mapTest1.get("key")) // 输出value//用数组作为keylet arrKey = [1,2,3,4,5];mapTest1.set(arrKey,"value2")console.info(mapTest1.get(arrKey)) // 输出value2// 用数组构造函数let mapTest2 = new Map([['key1','abc'],['key2','def']]);console.info(mapTest2.get('key1')) // abc//map长度console.info(mapTest2.size) //2//其他方法mapTest2.delete("key")mapTest2.clear()//遍历与set一样

WeakMap

WeakMap和WeakSet的特性一样,键必须是对象。

Proxy

      /* proxy */let objTest1 = {name: 'thatway',age: '18'} //代理objTest1,让用户去操作proxyTest,实际数据是存在于objTest1 //第一个参数是要代理的对象 //第二个参数是要拦截的各种配置let proxyTest = new Proxy(objTest1,{ //拦截对象的读取get(target,key){return target[key]+"哦"}, //拦截赋值操作set(target,key,value){return target['key']= value+"哦"}, //拦截in操作,是否存在has(target,key){if(key == 'name'){return false}}, //拦截deletedeleteProperty(target,key){if(key == 'name'){delete target[key]return true}else{return target[key]}},})console.info(proxyTest.name) //thatway哦proxyTest.name = "wp"console.info(proxyTest) //name值被设置为wp哦console.info(name in proxyTest); //falseconsole.info(delete proxyTest.name) //trueconsole.info(delete proxyTest.age) //trueconsole.info(proxyTest) //对象中没有了name,age还存在

proxy的操作
- get
get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy[‘foo’]。
- set
set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy[‘foo’] = v,返回一个布尔值。
- has
has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
- deleteProperty
deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
- ownKeys
ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy),返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
- getOwnPropertyDescriptor
getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
- defineProperty
defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
- preventExtensions
preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
- getPrototypeOf
getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
- isExtensible
isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
- setPrototypeOf
setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
- apply
apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。
- construct
construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(…args)。

reflect

refect方法与proxy一一对应。

     /* reflect *///字母是反射的意思//Reflect不用newconsole.info(Reflect.get(objTest,'name')) //thatwayconsole.info(Reflect.set(objTest,'key','value'))console.info(objTest)

reflect的设计目的,阮大神的文档中是这么说的:
1、 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。

2、修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。

3、让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。

4、Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

Proxy与Reflex结合实例

      //声明一个方法,返回值是一个代理对象,参数是实际对象和验证规则对象//其目的是为了给原对象做一些列数据格式验证,用户在使用对象时拿到的实际上是代理对象,而不是实际对象//这样的话就能够在用户填充数据时做一层拦截let validator = (obj,validatorConfig)=> {return new Proxy(obj,{_validatorConfig:validatorConfig,set(target,key,value,receiver){if(target.hasOwnProperty(key)){let validateAction = this._validatorConfig[key];if(!!validateAction(value)){return Reflect.set(target,key,value,receiver)}else{throw Error(`不能设置${key}到${value}`)}}else{throw Error(`${key}不存在`)}}});}//针对man对象的数据验证const manValidator = {name(val){return typeof val === 'string'},age(val){return typeof val === 'number' && val > 18}}//创建对象class Man{constructor(name,age=18){this.name= namethis.age= agereturn validator(this,manValidator)}}let manTest = new Man()
//      manTest.name = 123 // Error: 不能设置name到123manTest.name = 'thatway'console.info(manTest) // 输出对象,其中name为thatway,age为18//      manTest.age = '20'// Error: 不能设置age到20manTest.age = 20console.info(manTest) // 输出对象,其中name为thatway,age为20manTest.sex = 'boy' // Error: sex不存在

class

es6中定义类的关键字是class,不是Class

      /* class *///定义类class Parent{constructor(name='thatway'){this.name= name}}//实例化let thatway = new Parent('wp');console.log(thatway); //打印 Object { name: "wp" }//继承类class Child extends Parent{}let child1 = new Child()console.info(child1) //Object { name: "thatway" }let child2 = new Child('tutu')console.info(child2) //Object { name: "tutu" }class Tutu extends Parent{constructor(name='child',type){//子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象super(name)this.type = type}}let tutu1 = new Tutu()console.info(tutu1) //Object { name: "child", type: undefined }let tutu2 = new Tutu('tutu','boy')console.info(tutu2)//Object { name: "tutu", type: "boy" }//getter、setterclass P{constructor(name='thatway'){this.name = name}set title(value){this.name = value}get title(){return this.name}}let p = new P()p.title = '123'console.info(p.title)//123console.info(p)//Object { name: "123" }//静态方法class S{constructor(name='thatway'){this.name = name}static sing(){console.info('金色的河蓝色的海,都有我们快乐的身影...')}}console.info(S.sing()) //金色的河蓝色的海,都有我们快乐的身影...//静态属性,静态属性不使用static关键字,目前的方案是直接赋值S.age = 18console.info(S.age) //18

promise

     // 使js异步操作更加合理强大//es5中ajax回调模式function ajax5(callback){console.info("ajax5-1")setTimeout(function(){callback&&callback()})console.info("ajax5-2")}ajax5(function(){console.info("callback5");})//es6 promise方式let ajax6 = ()=> {console.info("ajax6-1")return new Promise((resolve,reject)=>{console.info("ajax6-2")setTimeout(()=>{resolve()},1000)})}ajax6().then(()=>{console.info("callback6")})let ajaxSencond = ()=>{return new Promise((resolve,reject)=>{return reject(new Error('second error'))})}//promise实例的then方法返回一个新的promise实例,所以可以链式调用,这样就可以将多个异步操作变得有序//第一个then返回的结果,会作为第二个then的参数//then是有顺序的ajax6().then(((data)=>{console.info("ajax6 succ")return "ajax6 rs"}),(data)=>{console.info("ajax6 error")}).then((data)=>{console.info("第二个then的resolve接收到的参数,可以拿着异步返回的结果做下面的逻辑了:"+data)ajaxSencond().then((data)=>{console.info("ajaxSencond succ")},(data)=>{console.info(data)})},(data)=>{console.info("ajax6 error")})//异常的捕获,建议用catchajaxSencond().then((data)=>{},(data)=>{console.info("异常在这里出现-回调")})ajaxSencond().then((data)=>{}).catch(function(data){console.info("异常在这里出现-catch")})//all 所有的promise都返回结果以后才会then,如果其中一个失败了,则直接用失败的结果let pro1 = new Promise((resolve,reject)=>{return resolve("data1")})let pro2 = new Promise((resolve,reject)=>{return resolve("data2")})Promise.all([pro1,pro2]).then(([data1,data2])=>{console.info(data1,data2)}).catch(function(error){console.info(error)}) //data1 data2let pro3 = new Promise((resolve,reject)=>{return reject(new Error('pro3 error'))})let pro4 = new Promise((resolve,reject)=>{return resolve("data4")})Promise.all([pro3,pro4]).then(([data3,data4])=>{console.info(data3,data4)}).catch(function(error){console.info(error)}) //Error: pro3 error//raceall不一样的是,哪个先返回结果就用哪个的结果,其他的不用了let pro5 = new Promise((resolve,reject)=>{setTimeout(function(){return resolve("data5")},100)})let pro6 = new Promise((resolve,reject)=>{return resolve("data6")})Promise.race([pro5,pro6]).then((data)=>{console.log(data)}).catch((data)=>{console.log(data)}) //data6

iterator

      /* Iterator *///数据集合结构的统一遍历方法//具有Symbol.iterator属性的数据结构就可以使用for of循环遍历function Obj(value) {this.value = value;this.next = null;}Obj.prototype[Symbol.iterator] = function() {var iterator = { next: next };var current = this;function next() {if (current) {var value = current.value;current = current.next;return { done: false, value: value };} else {return { done: true };}}return iterator;}var one = new Obj(1);var two = new Obj(2);var three = new Obj(3);one.next = two;two.next = three;for (var i of one){console.log(i); // 1, 2, 3}//      原生具备 Iterator 接口的数据结构如下。
//
//      Array
//      Map
//      Set
//      String
//      TypedArray
//      函数的 arguments 对象
//      NodeList 对象

Gernerator

      /* Generator */// generator是es6中的另一个异步解决方法//基本定义let tell = function* (){yield 'a';yield 'b';return 'c'}let rs = tell()console.info(rs.next()) //Object { value: "a", done: false }console.info(rs.next()) //Object { value: "b", done: false }console.info(rs.next()) //Object { value: "c", done: true } 有return的时候done会变为trueconsole.info(rs.next()) //Object { value: undefined, done: true }//Generator返回的就是一个Iteratorlet obj = {}obj[Symbol.iterator] = function* (){yield '1';yield '2';return}for(let val of obj){console.info(val)}//Generator应用场景:状态机//123三种状态let state = function* (){while (true){yield 1;yield 2;yield 3;}}let status = state();for(let i = 0;i<= 10;i++){console.info(status.next()) //一直是123依次输出}//抽奖次数限制let action = (count)=> {//抽一次奖品console.info(`剩余${count}次`)}let timesController = function* (count){while(count > 0){count --yield action(count)}}let times = 5let lottry = timesController(times)lottry.next()lottry.next()lottry.next()lottry.next()lottry.next()lottry.next()//长轮询实例let ajax = function* (){//yield返回一个promise实例yield new Promise((resolve,reject)=> {//异步耗时1秒钟后返回结果  setTimeout(()=>{return resolve('ok')},1000)})}//查询方法let pull = ()=> {//拿到Generatorlet generator = ajax()//执行ajaxlet step = generator.next()// step.value是返回的promisestep.value.then((data)=>{//如果结果不是期望的,1秒以后再一次调用,直到结果是期望的 if(data != 'ok'){setTimeout(()=>{console.info("等待1秒后再轮询")pull()},1000)}else{console.info('结束了:'+data)}})}//开始拉取数据 pull()

Decorators

这个api需要插件支持

npm i babel-plugin-transform-decorators-legacy -D

.babelrc中添加插件

"plugins": ["transform-decorators-legacy"]
      /* Decorator 修饰器 */// 是一个函数// 修改行为(可以修改或者扩展行为)// 类的行为 (只能在类上使用)// 类似于java的注解//声明一个修饰器let decoratorReadOnly = function(target,name,descriptor){descriptor.writable = falsereturn descriptor}//修饰某一个类的行为class Test{@decoratorReadOnlygetName(){return 'thatway'}}let test = new Test()test.getName = function(){return 'new'}//TypeError: "getName" is read-only//也可以放在类前修饰类let typeDecorator = function(target,name,descriptor){target.name = 'a'}@typeDecoratorclass Empty{}console.info('修饰类',Empty.name) //"name" is read-only//日志埋点let log = (type)=> {return function(target,name,descriptor){let src_method = descriptor.valuedescriptor.value =(...args)=>{src_method.apply(target,args)console.info(`log ${type}`)}}}class logTestObj {@log('method1')method1(){console.info('method1')}@log('method2')method2(){console.info('method2')}}let o = new logTestObj()o.method1()o.method2()

core-decorators包已经封装了常见的修饰符

npm i core-decorators

模块

模块主要涉及到import和export的语法,有几种不同情况下不同的写法。

学习资料

关于es6的入门,阮一峰大神已经整理的非常易懂了:

阮大神的babel介绍和ES6手册
http://www.ruanyifeng.com/blog/2016/01/babel.html
http://es6.ruanyifeng.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jquery插件封装指南

入门 编写一个jQuery插件开始于给jQuery.fn加入​​新的功能属性&#xff0c;此处添加的对象属性的名称就是你插件的名称&#xff1a; jQuery.fn.myPlugin function(){//你自己的插件代码};用户非常喜欢的$符号哪里去了&#xff1f; 它仍然存在&#xff0c;但是&#xff0c;为…

synchronize原理

synchronized的三种应用方式 一. 修饰实例方法&#xff0c;作用于当前实例加锁&#xff0c;进入同步代码前要获得当前实例的锁。 二. 修饰静态方法&#xff0c;作用于当前类对象加锁&#xff0c;进入同步代码前要获得当前类对象的锁。 三. 修饰代码块&#xff0c;指定加锁对象&…

不能修改“System Roots”钥匙串

iOS mac添加证书 不能修改“System Roots”钥匙串错误 如图&#xff1a; 解决方式&#xff1a; 打开钥匙串---登录---&#xff0c;直接把证书拖过来 然后&#xff0c;查看--我的证书&#xff0c;里面&#xff0c;找到证书&#xff0c;即可

stylus在vue中的使用

stylus是一个css预处理器&#xff0c;比较流行的css预处理器有sass、less、stylus&#xff0c;它们都一样&#xff0c;都是css的语法糖&#xff0c;可以使用变量&#xff0c;可以有简单的逻辑&#xff0c;使css的开发效率更高&#xff0c;更易维护。stylus来自node社区&#xf…

未来产品的设计

Donald A. Norman继《情感化设计》之后&#xff0c;又一设计精品力作&#xff1a; 未来产品的设计样章试读及本书预定&#xff1a;http://www.china-pub.com/195642市场价 &#xff1a;&#xffe5;39.00 会员价 &#xff1a; &#xffe5;29.25(75折) 【作  者】(美)Donald…

vue-cli webpack 配置分析

目录结构 . ├── README.md ├── build │ ├── build.js │ ├── check-versions.js │ ├── dev-client.js │ ├── dev-server.js │ ├── utils.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.c…

css之字体图标

SVG与字体图标 SVG图片是矢量图片&#xff0c;不会随着图片的伸缩而影响质量&#xff0c;通常把只有一种颜色的图标做成SVG&#xff0c;通过SVG生成字体图标&#xff0c;放到项目中使用。 https://icomoon.io/是一个比较快捷的生成字体图标的线上工具&#xff0c;进入主页后&…

history.back(-1)和history.go(-1)的区别

history.back(-1):直接返回当前页的上一页&#xff0c;数据全部消息&#xff0c;是个新页面 history.go(-1):也是返回当前页的上一页&#xff0c;不过表单里的数据全部还在 history.back(0) 刷新 history.back(1) 前进 history.back(-1) 后退

研发阶段模拟接口数据

因为在vue-cli工程中需要创建很多.vue文件&#xff0c;我们希望创建vue文件和创建html、css、js文件一样右键即可选择创建&#xff0c;并且创建的文件中可预先写好模板代码。 webstorm-Preferences打开选项界面 选择File and Code Templates&#xff0c;点击绿色加号 填…

真实项目中 ThreadLocal 的妙用

一、什么是 ThreadLocal ThreadLocal 提供了线程的局部变量&#xff0c;每个线程都可以通过 set() 和 get() 来对这个局部变量进行操作&#xff0c;但不会和其他线程的局部变量冲突&#xff0c;实现了线程间的据隔离。 简单讲&#xff1a;一个获取用户的请求线程 A&#xff0c;…

css之flex布局

flex布局是css3中的重要布局方式&#xff0c;称为“弹性布局”&#xff0c;每次想到它主要是遇到元素垂直居中、元素宽高自适应的问题&#xff0c;这些问题在flex中都能过简单设置就解决&#xff0c;它更像是原生APP中的布局操作&#xff0c;布局不必写N多的盒模型代码来实现&a…

javascript对URL中的参数进行简单加密处理

javascript的api本来就支持Base64&#xff0c;因此我们可以很方便的来进行编码和解码。 var encodeData window.btoa("namexiaoming&age10")//编码 var decodeData window.atob(encodeData)//解码。 下面来个具体的例子来说明如何对url中参数进行转码&#xff…

Fibinary Numbers

http://acm.hust.edu.cn/vjudge/contest/view.action?cid30506#problem/V 题意&#xff1a;从右向左&#xff0c;每一个位数&#xff0c;分别表示一个fibonacci数&#xff0c;1表示有&#xff0c;0表示没有&#xff1b;求两个数的和&#xff0c;同样按照这种形式存储 #include…

移动web开发DRP问题

DPR dpr问题是移动端web开发上需要注意的问题&#xff0c;用大白话说就是&#xff0c;代码中所设置的像素值实际上是虚拟像素&#xff0c;手机屏幕上的像素实际为物理像素&#xff0c;原始的手机&#xff0c;虚拟像素与物理像素是1:1覆盖的&#xff0c;但随着移动端屏幕的技术发…

HTML元素title里面如何换行

在调试代码的时候我就遇到一个问题&#xff0c;HTML元素title里面通常只显示一行&#xff0c;那我想要他换行&#xff0c;就是多行显示&#xff0c;如何实现&#xff1f;JS代码里面比如Alert里面又该如何换行&#xff1f; 经过我的一番实验 要实现这种效果有几种方法&#xff0…

A20 GPIO中断类型差别结果迥异的问题思考

A20GPIO中断类型差别结果迥异的问题思考 最近在使用全志A20做开发时&#xff0c;发现在处理中断的时候&#xff0c;用电平触发模式&#xff0c;报中断比较乱&#xff0c;用边沿触发则很稳定&#xff0c;不会乱报。笔者感到比较困惑&#xff0c;笔者用电平触发写的code如下&…

div内图片和文字水平垂直居中

大小不固定的图片、多行文字的水平垂直居中 本文综述 想必写css的都知道如何让单行文字在高度固定的容器内垂直居中&#xff0c;但是您知道或者想过让行数不固定的文字在高度固定的容器内垂直居中呢&#xff1f;本文将会告诉你如何实现多行文字的垂直居中显示。 关于图片垂直居…

sticky-footer实现记录

sticky-footer是css中的一个经典问题&#xff1a; 当页面内容超出屏幕&#xff0c;页脚模块会像正常页面一样&#xff0c;被推到内容下方&#xff0c;需要拖动滚动条才能看到。 而当页面内容小于屏幕高度&#xff0c;页脚模块会固定在屏幕底部&#xff0c;就像是底边距为零的…

敏友的【敏捷个人】有感(3): 有感于“敏捷个人”讨论与练习

2010年我对个人管理进行了自己的一些思考&#xff0c;在2011年提出敏捷个人概念&#xff0c;并且在线上、线下进行了多次交流&#xff0c;在一些大会上也做过分享。现在&#xff0c;已经有很 多IT和非IT的敏友们知道并在践行敏捷个人&#xff0c;帮助自己更快的成长。我收到大家…

jQuery编写插件

引言&#xff1a; 在项目中不同页面经常要用到已经写好的交互&#xff0c;比如弹窗&#xff0c;比如下拉菜单&#xff0c;比如选项卡&#xff0c;比如删除... 此时如果每次都把代码copy一份无疑是一件比较麻烦并且无趣的事情&#xff0c;而且个人认为有些low了&#xff0c;我们…