关系经济人类预测化学自然
中准网
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

前端必备之JavaScript进阶知识点

1月25日 火凤派投稿
  本文内容主要是面试复习准备、查漏补缺、深入某知识点的引子、了解相关面试题及底下涉及到的知识点,都是一些面试题底下的常用知识点,而不是甩一大堆面试题给各位,结果成了换个题型就不会的那种自定义事件
  自定义事件可以传参的和不可以传参的定义方式不一样,看代码吧注册事件不可以添加参数leteve1newEvent(myClick)可以添加参数leteve2newCustomEvent(myClick,params)监听事件dom。addEventListener(myClick,function(){console。log(myClick)})触发事件dom。dispatchEvent(eve1)复制代码var、let、const
  区别
  var
  let
  const
  是否有块级作用域
  是否初始化提升
  是否可以重复声明
  是否可以重新赋值
  是否必须设置初始值
  是否添加全局属性
  是否存在暂时性死区
  暂时性死区:创建了变量(有变量提升),但是没有初始化,没法使用变量,直接使用就会进入暂时性死区Set、Map
  Set和Map都是强引用(下面有说明),都可以遍历,比如forofforEach
  Set
  允许存储任何类型的唯一值,只有键值(key)没有键名,常用方法add、size、has、delete等等,看下用法constset1newSet()set1。add(1)constset2newSet(〔1,2,3〕)set2。add(沐华)console。log(set1){1}console。log(set2){1,2,3,沐华}console。log(set2。size)4console。log(set2。has(沐华))trueset2。delete(沐华)console。log(set2){1,2,3}用Set去重constset3newSet(〔1,2,1,1,3,2〕)constarr〔。。。set3〕console。log(set3){1,2,3}console。log(arr)〔1,2,3〕引用类型指针不一样,无法去重constset4newSet(〔1,{name:沐华},1,2,{name:沐华}〕)console。log(set4){1,{name:沐华},2,{name:沐华}}引用类型指针一样,就可以去重constobj{name:沐华}constset5newSet(〔1,obj,1,2,obj〕)console。log(set5){1,{name:沐华},2}复制代码
  Map
  是键值对的集合;常用方法set、get、size、has、delete等等,看下用法constmap1newMap()map1。set(0,1)map1。set(true,2)map1。set(function(){},3)constmap2newMap(〔〔0,1〕,〔true,2〕,〔{name:沐华},3〕〕)console。log(map1){01,true2,function(){}3}console。log(map2){01,true2,{}3}console。log(map1。size)3console。log(map1。get(true))2console。log(map1。has(true))truemap1。delete(true)console。log(map1){01,function(){}3}复制代码WeakSet、WeakMap
  WeakSet和WeakMap都是弱引用,对GC更加友好,都不能遍历
  比如:letobj{}
  就默认创建了一个强引用的对象,只有手动将objnull,在没有引用的情况下它才会被垃圾回收机制进行回收,如果是弱引用对象,垃圾回收机制会自动帮我们回收,某些情况下性能更有优势,比如用来保存DOM节点,不容易造成内存泄漏
  WeakSet
  成员只能是对象或数组,方法只有add、has、delete,看下用法constws1newWeakSet()letobj{name:沐华}ws1。add(obj)ws1。add(function(){})console。log(ws1){function(){},{name:沐华}}console。log(ws1。has(obj))truews1。delete(obj)console。log(ws1。has(obj))false复制代码
  WeakMap
  键值对集合,只能用对象作为key(null除外),value可以是任意的。方法只有get、set、has、delete,看下用法constwm1newWeakMap()consto1{name:沐华},o2function(){},o3windowwm1。set(o1,1){{name:沐华}:1}这样的键值对wm1。set(o2,undefined)wm1。set(o1,o3);value可以是任意值,包括一个对象或一个函数wm1。set(wm1,wm2);键和值可以是任意对象,甚至另外一个WeakMap对象wm1。get(o1);1获取键值wm1。has(o1);true有这个键名wm1。has(o2);true即使值是undefinedwm1。delete(o1);wm1。has(o1);false复制代码数据类型
  基础类型:Number,String,Boolean,undefined,null,Symbol,BigInt
  复杂类型:Object(FunctionArrayDateRegExpMathSetMap。。。)类型检测
  typeof
  基础(原始)类型typeof1numbertruetypeofastringtruetypeoftruebooleantruetypeofundefinedundefinedtruetypeofSymbol()symboltrue复制代码
  引用类型typeofnullobjecttruetypeof{}objecttruetypeof〔〕objecttruetypeoffunction(){}functiontrue复制代码
  用typeof判断引用类型就很尴尬了,继续看别的方法吧
  instanceof
  判断是否出现在该类型原型链中的任何位置,判断引用类型可还行?一般判断一个变量是否属于某个对象的实例console。log(nullinstanceofObject)falseconsole。log({}instanceofObject)trueconsole。log(〔〕instanceofObject)trueconsole。log(function(){}instanceofObject)true复制代码
  toStringlettoStringObject。prototype。toStringconsole。log(toString。call(1))〔objectNumber〕console。log(toString。call(1))〔objectString〕console。log(toString。call(true))〔objectBoolean〕console。log(toString。call(undefined))〔objectUndefined〕console。log(toString。call(null))〔objectNull〕console。log(toString。call({}))〔objectObject〕console。log(toString。call(〔〕))〔objectArray〕console。log(toString。call(function(){}))〔objectFunction〕console。log(toString。call(newDate))〔objectDate〕复制代码
  这个还不错吧
  其他判断constructor判断是否是该类型直接继承者letAfunction(){}letBnewA()A。constructorObjectfalseA。constructorFunctiontrueB。constructorFunctionfalseB。constructorAtrue判断数组console。log(Array。isArray(〔〕))true判断数字functionisNumber(num){letreg〔09〕。?〔09〕if(reg。test(num)){returntrue}returnfalse}封装获取数据类型functiongetType(obj){lettypetypeofobjif(type!object){returntype}returnObject。prototype。toString。call(obj)}含隐式类型转换继续往下看判断数字functionisNumber(num){returnnumnum}判断字符串functionisString(str){returnstrstr}判断布尔值functionisBoolean(bool){returnbool!!bool}复制代码类型转换
  JS没有严格的数据类型,所以可以互相转换显示类型转换:Number(),String(),Boolean()隐式类型转换:四则运算,判断语句,Native调用,JSON方法
  显示转换
  1。Number()console。log(Number(1))1console。log(Number(1))1console。log(Number(1a))NaNconsole。log(Number(true))1console。log(Number(undefined))NaNconsole。log(Number(null))0console。log(Number({a:1}))NaN原因往下看复制代码
  原始类型转换数值:转换后还是原来的值字符串:如果可以被解析成值,则转为相应的值,否则得到NaN,空字符串得到0布尔值:true转为1,false转为0undefined:转为NaNnull:转为0
  引用类型转换leta{a:1}console。log(Number(a))NaN原理a。valueOf(){a:1}a。toString()〔objectObject〕Number(〔objectObject〕)NaN复制代码先调用对象自身的valueOf方法,如果该方法返回原始类型的值(数值、字符串和布尔值),则直接对该值使用Number方法,不再继续如果valueOf方法返回复合类型的值,再调用对象自身的toString方法,如果toString方法返回原始类型的值,则对该值使用Number方法,不再继续如果toString方法返回的还是复合类型的值,则报错
  2。String()console。log(String(1))1console。log(String(1))1console。log(String(true))trueconsole。log(String(undefined))undefinedconsole。log(String(null))nullconsole。log(String({b:1}))〔objectObject〕原因往下看复制代码
  原始类型转换数值:转换成相应字符串字符串:转换后还是原来的值布尔值:true转为true,false转为falseundefined:转为undefinednull:转为null
  引用类型转换letb{b:1}console。log(String(b))〔objectObject〕原理b。toString()〔objectObject〕b。valueOf()由于返回的不是复合类型所以没有调valueOf()String(〔objectObject〕)〔objectObject〕复制代码先调用toString方法,如果toString方法返回的是原始类型的值,则对该值使用String方法,不再继续如果toString方法返回的是复合类型的值,再调用valueOf方法,如果valueOf方法返回的是原始类型的值,则对该值使用String方法,不再继续如果valueOf方法返回的是复合类型的值,则报错
  3。Boolean()console。log(Boolean(0))flaseconsole。log(Boolean(0))flaseconsole。log(Boolean())flaseconsole。log(Boolean(null))flaseconsole。log(Boolean(undefined))flaseconsole。log(Boolean(NaN))flase复制代码
  原始类型转换00nullundefinedNaN
  以上统一转为false,其他一律为true
  隐式转换四则运算如把String隐式转换成Numberconsole。log(11)true判断语句如把String隐式转为Booleanif(1)console。log(true)trueNative调用如把Object隐式转为Stringalert({a:1})〔objectObject〕console。log((〔〕〔〔〕〕〔〕)〔!!〔〕〕(〔〕{})〔!〔〕!!〔〕〕)nbJSON方法如把String隐式转为Objectconsole。log(JSON。parse({a:1})){a:1}复制代码
  几道隐式转换题console。log(truetrue)2解:true相加是用四则运算隐式转换Number就是11console。log(1{a:1})1〔objectObject〕解:上面说了Native调用{a:1}为〔objectObject〕数字1字符串直接拼接console。log(〔〕〔〕)解:String(〔〕)》〔〕。toString()》》console。log(〔〕{})〔objectObject〕解:String({})》{}。toString()〔objectObject〕》〔objectObject〕console。log({}〔〕)0解:{}当作代码块不执行,〔〕转为,结果是就是0console。log({}{})谷歌和Node:〔objectObject〕〔objectObject〕火狐:NaN复制代码
  运算符优先级,图来自MDN
  this
  它指向什么完全取决于函数在哪里调用,在Es5中this永远指向调用它的那个对象,而在Es6的箭头函数中没有this绑定,this指向箭头函数定义时所在的作用域中的this
  判断this全局作用域、自执行函数、定时器传进的非箭头函数的this都指向window严格模式(usestrict)下的this指向undefined构造函数中的this指向当前的实例事件绑定函数中的this指向当前被绑定的元素箭头函数中this指向定义箭头函数的上级作用域中的this
  改变this指向使用call,apply,bind,call和apply改变this指向时,函数会立即执行,bind不会保存成变量(letselfthis)使用箭头函数使用new实例化一个对象严格模式下直接调用函数this指向undefined
  箭头函数硬绑定的this无法被修改,比如fn。call(window),再把fn赋值给对象的属性后,调用对象的方法this依然是window箭头函数箭头函数写法更简洁箭头函数本身没有this,所以没有prototype箭头函数不支持new箭头函数的this继承自外层第一个作用域的this,严格和非严格模式下都一样,修改被继承的this指向,那么箭头函数的this指向也会跟着改变箭头函数指向全局时,arguments会报错,否则arguments继承自外层作用域箭头函数不支持函数形参重名闭包
  闭包是指一个函数有权访问外部作用域中的变量,这个函数就是闭包,所以所有的JS函数都是闭包,因为他们都是对象,都关联到了作用域链
  优点:内部函数有权访问外部函数的局部变量
  缺点:内部函数引用的变量会在内存中,不会立刻销毁;因为内部函数有权访问外部函数,所以外部函数执行完了也不会被垃圾回收,而占用内存;如果闭包用得太多会导致性能降低浅拷贝
  第一层是引用类型就拷贝指针,不是就拷贝值。拷贝栈不拷贝堆1。展开运算符。。。letobj1{a:1,b:{c:3}}letobj2{。。。obj1}obj1。aaobj1。b。ccconsole。log(obj1){a:a,b:{c:c}}console。log(obj2){a:1,b:{c:c}}2。Object。assign()把obj2合并到obj1Object。assign(obj1,obj2)3。手写functionclone(target){letobj{}for(letkeyintarget){obj〔key〕target〔key〕}returnobj}4。数组浅拷贝用Array方法concat()和slice()letarr1〔1,2,{c:3}〕letarr2arr1。concat()letarr3arr1。slice()复制代码深拷贝
  拷贝栈也拷贝堆,重新开僻一块内存
  1。JSON。parse(JSON。stringify())letobj1{a:1,b:{c:3}}letobj2JSON。parse(JSON。stringify(obj1))obj1。aaobj1。b。ccconsole。log(obj1){a:a,b:{c:c}}console。log(obj2){a:1,b:{c:3}}复制代码
  该方法可以应对大部分应用场景,但是也有很大缺陷,比如拷贝其他引用类型,拷贝函数,循环引用等情况
  2。手写递归
  原理就是递归遍历对象数组,直到里面全是基本类型为止再复制
  需要注意的是属性引用了自身的情况,就会造成循环引用,导致栈溢出
  解决循环引用可以额外开僻一个存储空间,存储当前对象和拷贝对象的关系,当需要拷贝对象时,先去存储空间找,有木有这个拷贝对象,如果有就直接返回,如果没有就就继续拷贝,这就解决了
  这个存储空间可以存储成keyvalue的形式,且key可以是引用类型,选用Map这种数据结构。检查map中有木有克隆过的对象,有就直接直接返回,没有就将当前对象作为key,克隆对象作为value存储,继续克隆functionclone(target,mapnewMap()){if(typeoftargetobject){引用类型才继续深拷贝letobjArray。isArray(target)?〔〕:{}考虑数组防止循环引用if(map。get(target)){returnmap。get(target)有拷贝记录就直接返回}map。set(target,obj)没有就存储拷贝记录for(letkeyintarget){obj〔key〕clone(target〔key〕)递归}returnobj}else{returntarget}}复制代码
  优化版用WeakMap替代Map,上面说了WeakMap是弱引用,Map是强引用选择性能更好的循环方式
  forin每次迭代操作会同时搜索实例和原型属性,会产生更多的开销,所以用while用while来实现一个通用的forEach遍历functionforEach(array,iteratee){letindex1;constlengtharray。while(indexlength){iteratee(array〔index〕,index);}}WeakMap对象是键值对集合,键必须是对象,而且是弱引用的,值可以是任意的functionclone(target,mapnewWeakMap()){引用类型才继续深拷贝if(targetinstanceofObject){constisArrayArray。isArray(target)克隆对象和数组类型letcloneTargetisArray?〔〕:{}防止循环引用if(map。get(target)){有拷贝记录就直接返回returnmap。get(target)}没有就存储拷贝记录map。set(target,cloneTarget)是对象就拿出同级的键集合返回是数组格式constkeysisArray?undefined:Object。keys(target)value是对象的key或者数组的值key是下标forEach(keystarget,(value,key){if(keys){是对象就把下标换成valuekeyvalue}递归cloneTarget〔key〕clone(target〔key〕,map)})returncloneTarget}else{returntarget}}复制代码new
  new干了什么?创建一个独立内存空间的空对象把这个对象的构造原型(proto)指向函数的原型对象prototype,并绑定this执行构造函数里的代码如果构造函数有return就返回return的值,如果没有就自动返回空对象也就是this
  有一种情况如下,就很坑,所以构造函数里面最好不要返回对象,返回基本类型不影响functionPerson(name){this。namenameconsole。log(this){name:沐华}return{age:18}}constpnewPerson(沐华)console。log(p){age:18}复制代码原型
  我们都知道new了一个新的实例之后,我们什么都没做就可以直接访问toString(),valueOf()等一些方法,那这些方法是从哪来的呢?
  答案就是原型,来我们先看一张图
  对照图片,我们看几行代码functionParent(){}这就是构造函数letchildnewParent()child就是实例Parent。prototype。getNamefunction(){console。log(沐华)}getName是构造函数的原型对象上的方法child。getName()沐华这是继承来的方法复制代码prototype:它是构造函数的原型对象。每个函数都会有这个属性,强调一下,是函数,其他对象是没有这个属性的proto:它指向构造函数的原型对象。每个对象都有这个属性,强调一下,是对象,同样,因为函数也是对象,所以函数也有这个属性。不过访问对象原型(child。proto)的话,建议用Es6的Reflect。getPrototypeOf(child)或者Object。getPrototypeOf(child)方法constructor:这是原型对象上的指向构造函数的属性,也就是说代码中的Parent。prototype。constructorParent是为true的原型链
  每个对象都有一个proto属性指向原型对象,原型对象也是对象,所以也有proto指向原型对象的原型对象,一层一层往上,形成起来的链式关系,就是原型链
  原型链也决定了js中的继承方式,当我们访问一个属性时:先访问对象的实例属性,找到就返回,没有就通过proto去原型对象中找在原型对象上找到,就返回,没有继续通过原型的proto向上层查找一直到Object。prototype,找到就返回,没有就返回undefined,不找了
  原型链的最上层对象就是Object,那Object构造函数的原型是谁?
  答案是自身,它的constructor指向Object,而它的proto则指向null原型污染
  原型污染是指攻击者通过某种手段修改js的原型Object。prototype。toStringfunction(){alert(原生方法被改写,已完成原型污染)};复制代码
  怎么解决原型污染用Object。freeze(obj)冻结对象,然后就不能被修改属性,变成不可扩展的对象Object。freeze(Object。prototype)Object。prototype。toStringhelloconsole。log(Object。prototype。toString)toString(){〔nativecode〕}复制代码不采用字面量形式,用Object。create(null)创建一个没有原型的新对象,这样不管对原型做什么扩展都不会生效constobjObject。create(null)console。log(obj。proto)undefined复制代码用Map数据类型,代替Object类型Map对象保存键值对的集合。任何值(对象或者原始值)都可以作为一个键或一个值。所以用Map数据结构,不会对Object原型污染Map和Object不同点Object的键只支持String或者Symbols两种类型,Map的键可以是任意值,包括函数、对象、基本类型Map中的键值是有序的,Object中的键不是Map在频繁增删键值对的场景下有性能优势用size属性直接获取一个Map的键值对个数,Object的键值对个数不能直接获取
  有一种情况JSON。parse({a:1,proto:{b:2}})复制代码
  结果不会改写Object。prototype,因为V8会自动忽略JSON。parse里面名为proto的键继承
  上面说了对象之间有一个原型对象指针proto关联,形成链式结构,所以一个对象就可以通过这个关联访问另一个对象的属性和函数,这就是继承
  ES6继承classParent(){constructor(props){this。name沐华}}继承classChildextendsParent{props是继承过来的属性,myAttr是自己的属性constructor(props,myAttr){调用父类的构造函数,相当于获得父类的this指向super(props)}}console。log(newChild()。name)沐华复制代码
  虽然现在都用ES6的class,但是ES5的继承面试还是会问
  ES5继承
  ES5的继承方式有很多种,什么原型链继承、组合继承、寄生式继承。。。等等,了解一种面试就够用了functionParent(){}Parent。prototype。getNamefunction(){return沐华}functionChild(){}方式一Child。prototypeObject。create(Parent。prototype)Child。prototype。constructorChild重新指定constructor方式二Child。prototypeObject。create(Parent。prototype,{constructor:{value:Child,writable:true,属性能不能修改enumerable:true,属性能不能枚举(可遍历性),比如在forinObject。keysJSON。stringifyconfigurable:true,属性能不能修改属性描述对象和能否删除}})console。log(newChild()。getName)沐华复制代码作用域
  作用域就是一个独立的地盘,能够访问和修改里面的值,并且变量不会外泄,不同作用域中同名变量也不会冲突
  Es6之前只有全局作用域和函数作用域,Es6新增了块级作用域(let和const)
  如图,在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量,或抵达最外层的全局作用域为止,如果还是没有找到就报错
  而这一层一层嵌套起来的作用域,就形成了作用域链
  做道题,理解作用域functionfoo(){console。log(a);}functionbar(){vara3;foo();}vara2;bar()复制代码数组
  记着会改变原数组的几个方法
  pop、push、shift、unshift、reverse、sort、splice、fill、copyWithin
  其他更多详细的可以参考这篇文章,总结的蛮好的
  JS数组方法总览及遍历方法耗时统计垃圾回收
  V8实现了GC算法,采用了分代式垃圾回收机制,所以V8将堆内存分为新生代(副垃圾回收器)和老生代(主垃圾回收器)两个部分新生代
  新生代中通常只支持18M的容量,所以主要存放生存时间较短的对象
  新生代中使用ScavengeGC算法,将新生代空间分为两个区域:对象区域和空闲区域。如图:
  顾名思义,就是说这两块空间只使用一个,另一个是空闲的。工作流程是这样的将新分配的对象存入对象区域中,当对象区域存满了,就会启动GC算法对对象区域内的垃圾做标记,标记完成之后将对象区域中还存活的对象复制到空闲区域中,已经不用的对象就销毁。这个过程不会留下内存碎片复制完成后,再将对象区域和空闲互换。既回收了垃圾也能让新生代中这两块区域无限重复使用下去
  正因为新生代中空间不大,所以就容易出现被塞满的情况,所以经历过两次垃圾回收依然还存活的对象会被移到老生代空间中如果空闲空间对象的占比超过25,为了不影响内存分配,就会将对象转移到老生代空间老生代
  老生代特点就是占用空间大,所以主要存放存活时间长的对象
  老生代中使用标记清除算法和标记压缩算法。因为如果也采用ScavengeGC算法的话,复制大对象就比较花时间了
  标记清除
  在以下情况下会先启动标记清除算法:某一个空间没有分块的时候对象太多超过空间容量一定限制的时候空间不能保证新生代中的对象转移到老生代中的时候
  标记清除的流程是这样的从根部(js的全局对象)出发,遍历堆中所有对象,然后标记存活的对象标记完成后,销毁没有被标记的对象
  由于垃圾回收阶段,会暂停JS脚本执行,等垃圾回收完毕后再恢复JS执行,这种行为称为全停顿(stoptheworld)
  比如堆中数据超过1G,那一次完整的垃圾回收可能需要1秒以上,这期间是会暂停JS线程执行的,这就导致页面性能和响应能力下降
  增量标记
  所以在2011年,V8从stoptheworld标记切换到增量标记。使用增量标记算法,GC可以将回收任务分解成很多小任务,穿插在JS任务中间执行,这样避免了应用出现卡顿的情况
  并发标记
  然后在2018年,GC技术又有重大突破,就是并发标记。让GC扫描和标记对象时,允许JS同时运行
  标记压缩
  清除后会造成堆内存出现内存碎片的情况,当碎片超过一定限制后会启动标记压缩算法,将存活的对象向堆中的一端移动,到所有对象移动完成,就清理掉不需要的内存事件循环
  关于事件循环知识点可以阅读我另一篇文章,介绍的很详细,这里就不复制过来了
  看完还不懂JavaScript执行机制(EventLoop),你来捶我Promise、async、await
  这几个主要都是考笔试题,所以只要会手写Promise的几个方法,知道事件循环,就肯定没问题了
  Promise构造函数是同步执行的,then方法是异步执行的(微任务)
  asyncawait本质上就是Promise,只不过她可以在不阻塞主线程的情况下,使用同步代码实现异步访问。
  缺点是await会阻塞代码,要是她之后的异步代码不依赖她的结果,也还是要等她完成,失去了并发性,这时候就建议用Promise。all
  看例子,顺便复习事件循环asyncfunctionfun(){console。log(1)letaawait2console。log(a)console。log(3)}console。log(4)fun()console。log(5)复制代码
  输出结果:41523
  结合asyncawait的特点,我们来把这个题用ES6翻译一下functionfun(){returnnewPromise((){console。log(1)Promise。resolve(2)。then(a{console。log(a)console。log(3)})})}console。log(4)fun()console。log(5)复制代码
  想研究一下Promise的可以看这篇文章Promise你真的用明白了么
  最后问一个问题:asyncawait经过编译后和generator有啥联系?手写代码
  这一块内容有点多,有手写:防抖、节流、new、bind、apply、call、instanceof、Promise、Promise。all、Promise。race、AJAX。。。。
  请移步看我另一篇文章基础很好?22个高频JavaScript手写代码总结了解一下结语
  零零散散的笔记一大堆,终于整合好了
  自己又复习了一遍,希望对大家也有帮助
  如果有说的不对的,或者遗漏的,欢迎大家指正
  作者:沐华
  链接:https:juejin。cnpost6995591618371780622
投诉 评论 转载

天空体育埃里克森将决定是否加盟曼联!尤文免签博格巴已成定局天空体育消息,埃里克森将在曼联和布伦特福德之间做出选择。报道称,曼联和布伦特福德都为30岁的埃里克森提供了丰厚的合同,不过相对来说,曼联的合同被认为财政上更有诱惑力,这名……初中时被霸凌想轻生多年后这种感觉,还想再经历一次人的一生,会有许许多多的起起落落。曾经最讨厌,最恨,最不想回忆的时光;或许,在多年后的岁月里,会以一种截然相反的态度去看待。那天晚上,他对我做的事,让我当时有推窗跳……经络到底是什么一、经络是什么?这要追溯到中国最古老的医学书《黄帝内经》。黄帝内经分成《素问》和《灵枢》两大部分。上部《素问》讲的是养生问题,大体就是要心态好,要按时起居,要顺应自然等等……邵兵被踢出剧组落魄时娶的妻子,是我今生的挚爱2000年,当红影星邵兵在《笑傲江湖》剧组里出演男一号令狐冲。但却被爆出在片场耍大牌,脾气狂躁且目中无人。惹得制片人张纪中大发雷霆,直骂想抽他。最后宁愿赔付一百万违……平均每天烧7辆,为什么说电动车自燃比燃油车更可怕?从以前无人问津,到现在热度高居不下,新能源汽车被消费者所追捧,似乎也就是几年光景的事情。而且伴随着这种趋势的上升,新能源汽车还很有可能在今年突破年销500万台的成绩,说一句新能……尼尔自动人形秘密房间新进展前作经典对白重现继reddit用户sadfutago日前发布两段视频,展示他在《尼尔自动人形》的复制都市发现隐藏门,以及进入其中后遇到疑似尼尔和悠娜的角色后,今天他又放出了两段新的后续视频,透……初秋第一双鞋!跪求你买这几双,好看到想报警很多姑娘都开始着手买秋装了吧,但有没有觉得,为什么同一件衣服,明明风格都get到位了,但还是差点意思?仔细看,是不是发现鞋子才是决定穿搭的关键!明明是同一件衣服配上……Epic平台游戏激活安装教程step1:登录官网地址:https:www,epicgames。comstorezhCN点击登录step2:有EPIC账号则直接将账号密码输入点击登录,没有账号的则点击……前端必备之JavaScript进阶知识点本文内容主要是面试复习准备、查漏补缺、深入某知识点的引子、了解相关面试题及底下涉及到的知识点,都是一些面试题底下的常用知识点,而不是甩一大堆面试题给各位,结果成了换个题型就不会……四维空间入口找到了原来是在这里四维空间入口是人的大脑四维空间入口找到了根据科学家认为宇宙存在11维度空间,很多人疑惑,我们连四维空间都未曾见过,谈何11维度空间,曾经有一位数学家提出一个克莱因瓶的理论……正式官宣!广东宏远三分神射确定复出,杜锋再进行阵容调整广东宏远第一阶段取得11胜2负的战绩,排名联盟第二的位置。在威姆斯没有归队的情况下,广东宏远阵容轮换面对一定的困难,本土球员伤病太多,杜润旺、胡明轩等核心都受到伤病的困扰,年轻……关于接收香港回归方案,邓小平曾说如果有阻碍,部队直接开进去1997年7月1日是每一个中国人都应该铭记的日子,在这一天香港回归了阔别近百年的祖国怀抱。这个在外漂泊了多年的游子终于回家,在这一天所有的中国人都感到无比的欣慰和自豪。香港的回……
30!西甲劲旅创25年纪录,再迎关键战,输球目送皇马夺冠晚安温馨句子短句简短晚安美句心理学也参与到公共长椅的设计中砍刀眉笔怎么用微商怎么加粉精准狙击目标的猎枪在这里稻盛和夫利人利世勇于自我牺牲,为对方尽力银屑病泡中药药浴有什么好处鹤望兰的繁殖方法有哪些我们,是时候长大了泡木耳的水能用吗岁美女凌晨独自一人回家楼梯间内取快递遭歹徒抢手机林志颖已经安全渡过危险期,特斯拉对林志颖车祸事故做出了回应
怦然心动我看到的不止美好的爱与善意,更有生活的启示热文蚂蚁集团退款到账酷派大神F2的屏幕尺寸是多少?分辨率是多少?小龙虾放啤酒了能吃头孢吗昭宣中兴对西汉造成了哪些影响如果可以选择,抚顺朝阳丹东和盘锦葫芦岛,你会选择住在哪里,为粽子飘香的端午豆瓣绿怎么养才茂盛描写四季的小学作文400字热闻聚热点网 泡芙中间是软是没熟吗泡芙中间是软是不是没熟有机米有副作用吗不再旷课保证书

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州