写出结果并说明原因leta={n:1};letb=a;a.x=a={n:2};console.log(a.x);console.log(b.x);知识点分析:知识点的优先级大于等号;等号从右到左执行第一步:a=b,所以a和b指向同一个内存地址第二步:根据知识点,点数优先级高,所以先执行a.x,即a和b都是{n:1,x:undefined}第三步:等号从右往左执行,即a变回{n:2}然后a指向{n:2}不再是之前的地址Step4:Executea.x=a.左边的a是旧的a,等于bb={n:1,x:{n:2}}output:undefined{n:2}expandleta={n:1};letb=a;b.n=a.f={n:2};console.log(a);console.log(b);输出:{n:{n:2},f:{n:2}},{n:{n:2},f:{n:2}}写出结果并解释为什么functionuser(obj){obj.name='aaa';对象=新对象();obj.name='bbb';}letperson=newObject();user(person);console.log(person.name);解析引用类型作为参数进入函数,即指向内存区被复制,可以理解为形参obj先由argument[0]赋值,即obj=argument[0]。person进入函数后,第一步argument[0]=person,即person的指针赋给argument[0]。当obj.name='aaa';因为argument[0]指针是person,而obj=argument[0],所以obj也指向person。所以person.name='aaa'对象。对象=新对象();创建一个新对象并将其指针复制到变量obj。此时obj的指针不再指向person。人的指针不会受影响,写出结果,并说明原因vara1={},b1='123',c1=123;a1[b1]='b';a1[c1]='c';console.log(a1[b1]);vara2={},b2=Symbol('123'),c2=Symbol('123');a2[b2]='b';a2[c2]='c';console.log(a2[b2]);vara3={},b3={key:'123'},c3={key:'456'};a3[b3]='b';a3[c3]='c';console.log(a3[b3]);知识点:1.对象的键名只能是string和Symbol类型2.其他类型的键名会转成string类型3.对象转string会默认调用toString方法4.Symbol是ES6中新加入的数据类型。Symbol本质上是一个唯一标识符,可以作为一个对象的唯一属性名,这样别人就不会改写或覆盖你设置的属性值解析:1.在a1中,a1[b1]='b';a1[c1]='c';c1的键名会被转换为字符串'123'覆盖b1,所以结果是'c'2。a2中,b2和c2都是Symbol类型,不需要转换,任何Symbol类型的值都不相等,所以不会被覆盖,结果为'b'3。a3中,b3和c3都是object类型,作为键名,会调用toString方法转换成字符串[objectObject],c3覆盖b3的值,结果为'c'结果:'c','b','c'写入结果并解释为什么asyncfunctionasync1(){console.log('async1start');等待async2();console.log('async1end');}asyncfunctionasync2(){console.log('async2');}console.log('scriptstart');setTimeout(()=>{console.log('setTimeout');},0)async1();newPromise((resolve)=>{console.log('promise1');resolve();}).then(()=>{console.log('promise2');});console.log('scriptend');知识点:1.一旦定义了Promise,就会立即执行2.Promise优先于setTimeout宏任务,所以setTimeout回调会最后执行3.Promise的resolve和reject是异步执行的回调。所以resolve()会被放入回调队列,在main函数执行前调用4.await,执行setTimeout,让线程出来。标有async的函数会返回一个Promise对象5.宏任务在微任务中先执行常见的宏任务:script,I/O,setTimeout,setInterval常见的微任务:Promise。扩展console.log('1');setTimeout(function(){console.log('2');process.nextTick(function(){console.log('3');})newPromise(function(resolve){console.log('4');resolve();}).then(function(){console.log('5')})})process.nextTick(function(){console.log('6');})newPromise(function(resolve){console.log('7');resolve();}).then(function(){console.log('8');})setTimeout(function(){console.log('9');process.nextTick(function(){console.log('10');})newPromise(function(resolve){console.log('11');resolve();}).then(function(){console.log('12')})})解析第一个宏任务:1、第一个宏任务脚本整体进入主线程,遇到consolee.log('1')output12.遇到setTimeout,宏任务(现在第一个宏任务脚本还没有执行,会赋值给宏任务,暂时不执行)3.遇到下面的过程。nextTick赋值给微任务4,遇到Promise,直接执行newPromise,输出7then分发给微任务EventQueue5,此时微任务表中:process.nextTick,Promise.then,执行结果为68第一个宏任务的执行结果:1768第二个宏任务:1.第二个宏任务是第一个setTimeout2.执行顺序和脚本一样。当遇到console.log('2')Execute2process.nextTick会被赋值给微任务Promise会立即执行然后.then会被赋值给微任务输出:2435第三个宏-task:第三个macro-task是第二个setTimeout和第二个macro-task执行顺序一样,输出结果9111012写结果并说明原因constnum={a:10,add(){返回this.a+2;},reduce:()=>this.a-2};console.log(num.add());console.log(num.reduce());分析:知识点函数体中的this对象是定义所在的对象,不是使用时的对象。add是一个普通函数,reduce是一个箭头函数。对于箭头函数,this指向它定义的环境,这与普通函数不同。这意味着当我们调用reduce时,它??不是指num对象,而是指定义它的环境(窗口)。a属性没有值,因此返回undefined。undefined-2ReturnNaN输出:NaN写出结果并解释为什么varfullname='a';varobj={fullname:'b',prop:{fullname:'c',getFullname:function(){returnthis.全名;}}};console.log(obj.prop.getFullname());vartest=obj.prop.getFullname;console.log(test());分析:对于第一个obj.prop.getFullname(),getFullname()作为obj.prop对象的方法被调用,所以此时的执行环境应该是这个对象。当把obj.prop.getFullname赋值给test变量时,此时的执行环境就变成了全局对象(window),因为test定义在全局范围内。因此,此时this指向全局作用域的fullname变量,即a写入结果并说明原因functionFoo(){Foo.a=function(){console.log(1);}this.a=function(){console.log(2)}}Foo.prototype.a=function(){console.log(3);}Foo.a=function(){console.log(4);}Foo.a();letobj=newFoo();obj.a();Foo.a();分析:Foo.a()这是调用Foo函数的静态方法a,虽然有一个Foo中优先级较高的属性方法a,但是此时并没有调用Foo,所以此时输出Foo的静态方法a的结果:4letobj=newFoo();new方法用于调用函数,返回函数实例对象。此时,Foo函数的内部属性方法被初始化,原型链建立。obj.a();调用obj实例上的方法a,目前有两个a方法:一个是内部属性方法,一个是原型上的方法。当两者都存在时,先查找ownProperty,如果不存在,则去原型链中查找,于是在实例上调用a,输出:2Foo.a();按照步骤2,已经初始化了Foo函数内部的属性方法,并覆盖了一个同名的静态方法,所以输出:1
