js笔试题(不定期更新)

第一题

//第一题
var a = {n:1};//创建对象{n:1},赋值给a
var b = a;//b引用a的对象,实际上此时内存只有一个对象。变量a,b同时指向这个对象
a.x = a = {n:2};//此时将这个对象的键值x赋值,赋值内容是运算表达式a={n:2}的运算结果{n:2}
//a={n:2}这个运算表达式又创建了一个对象{n:2},同时让a指向这个对象
//此时内存中有两个对象 a指向于新的对象{n:2},b指向于原对象{n:1,x:{n:2}}
console.log(a.x);// -->undefined
console.log(b.x);// -->{n:2}

//第二题
let obj={
    num1:117
}
let res=obj;
obj.child=obj={num2:935};
var x=y=res.child.num2;
console.log(obj.child);       
console.log(res.num1);       
console.log(y);  

以上第一题的另一种解析是:
首先 . 运算符优先级高于= ,所以先给{n:1}对象创建了x属性,对象变成{n:1,x:undefined}(当前a和b都是指向此内存对象),然后连等从右往左执行,先把a指向改成{n:2},然后把最初的内存对象的x属性指向改成{n:2}(因为.运算符已执行,所以此时a.x是指{n:1,x:undefined}的x属性),内存对象变成{n:1,x:{n:2}}。此时只有b还是指向这个内存对象 所以:
a.x -->undefined
b -->{n:1,x:{n:2}}

第二题

const obj={
	flag:true,
}
function a() {
	this.flag=false;
	return obj;
}
const A=new a();
console.log(A.flag);

第三题

    var num= 10
    let obj={num:20}
    obj.fn =(function(num){
        this.num= num *3;
        num++
        return function(n){
            this.num += n
            num++
            console.log(num)
        }
    })(obj.num)
    let fn= obj.fn 
    fn(5)
    obj.fn(10)
    console.log(num, obj.num)

第四题

    var a={},
        b={key:'b'},
        c={key:'c'};
    a[b]=123;
    a[c]=456;
    console.log(a[b]);
// 对象有两种方法设置和引用属性,obj.name和obj['name'],方括号里可以字符串、数字和变量设置是表达式等,但是最终计算出来得是一个字符串,
// 对于上面的b和c,它们两个都是对象,所以会调用toString()方法转成字符串,对象转成字符串和数组不一样,和内容无关,结果都是[object Obejct],所yi
// a[b]=a[c]=a['[object Object]']。

第五题

  function fruits() { }
     fruits.prototype = {
       color: 'red',
       say: function () {
         console.log(this.color);
       }
     };
     var apple = new fruits();
     apple.say();
     banana = { color: 'yellow' };
     apple.say.call(banana);
     apple.say.apply(banana);
     apple.say.apply(null);

第六题

     const promise = new Promise((resolve, reject) => {
       console.log(1);
       setTimeout(() => {
         console.log("begin");
         resolve("suss");
         console.log("end");
       }, 0);
       console.log(2);
    });
    promise.then((data) => { console.log(data); });
     console.log(4);

第七题

console.log(!![]);
console.log(!!'');

变量释放问题

//第一题
var a ="hello";//全局变量
window.b ="word";//全局变量
delete a;
delete b;
console.log(typeof a);//结果:string 
console.log(typeof b);//结果:undefined! 
!function b(){
    var c = 1;//局部变量
    d = 2;//全局变量
    delete c;
    delete d;
    console.log(typeof c);//结果:number
    console.log(typeof d);//结果:undefined
}()

//第二题
function A(x){
	this.x=x;
}
A.prototype.x=1;
function B(x){
	this.x=x;
}
B.prototype=new A();
var a=new A(2),b=new B(3);
delete b.x;
console.log(a.x);//2
console.log(b.x);//underfined

//第二题
let a=1;
let obj={
    x:1
}
delete a;
delete obj.x;
delete 2;
console.log(a);        
console.log(obj.x);        
console.log(2); 

结论:

  1. 使用var、let创建的变量不能使用delete释放内存
  2. 不使用var、let创建的变量可以使用delete释放内存

第八题

function Foo() {
    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();
let obj = new Foo();
obj.a();
Foo.a();  
  1. Foo.a() 这个是调用 Foo 函数的静态方法 a,虽然 Foo 中有优先级更高的属性方法 a,但 Foo 此时没有被调用,所以此时输出 Foo 的静态方法 a 的结果:4
  2. let obj = new Foo(); 使用了 new 方法调用了函数,返回了函数实例对象,此时 Foo 函数内部的属性方法初始化,原型链建立。
  3. obj.a() ; 调用 obj 实例上的方法 a,该实例上目前有两个 a 方法:一个是内部属性方法,另一个是原型上的方法。当这两者都存在时,首先查找 ownProperty ,如果没有才去原型链上找,所以调用实例上的 a 输出:2
  4. Foo.a() ; 根据第2步可知 Foo 函数内部的属性方法已初始化,覆盖了同名的静态方法,所以输出:1

第九题

		function fun() {
            return () => {
                return () => {
                    return () => {
                        console.log(this.name)
                    }
                }
            }
        }
        var f = fun.call({ name: 'foo' })
        var t1 = f.call({ name: 'bar' })()()
        var t2 = f().call({ name: 'baz' })()
        var t3 = f()().call({ name: 'qux' })

箭头函数没有自己的this也并不能使用call,apply以及bind去绑定this,会选择去继承父级作用域的this,所以后面几次的call实际上是失败的,所以箭头函数层层向上寻找name,只会在最外层的fun函数作用域中找到this指向{name: ‘foo’}对象的name属性。假设此处将fun函数改成箭头函数的声明方式,那么返回的值将会是undefined.

第十题

//第一例
var a=1
function fun(){
	var a=2
	console.log(a);//2
}
fun()
//第二例
var b=1;
for(var c=0;c<1;c++){
	var b=2;
}
console.log(b)//2

使用var声明的变量存在很大的问题。在本题中fun函数内部的作用域为局部作用域,log打印会优先找到局部作用域的a变量,所以打印为2.
而在第二例中,由于for循环内部对于使用var声明的变量不是一个局部作用域,所以for循环内部的变量声明会和外部的变量声明一起发生变量提升,所以b=2会覆盖前一个b=1,打印出2,这种情况同样适用于if判断。

第十一题

//第一例
async function async1() {
    console.log(1);
    const result = await async2();
    console.log(3);
}
async function async2() {
    console.log(2);
}
Promise.resolve().then(() => {
    console.log(4);
});
setTimeout(() => {
    console.log(5);
});
async1();
console.log(6);
//第二例
async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}
console.log('同步1');
setTimeout(() => {
    console.log('setTimeout');
}, 0)
async1();
new Promise((resolve) => {
    console.log('promise1');
    resolve();
}).then(() => {
    console.log('promise2');
});
console.log('同步2');
//第三例
Promise.resolve()
	.then(() => {
		console.log(0);
		return Promise.resolve(4);
	})
	.then((res) => {
        console.log(res);
	});
Promise.resolve()
	.then(() => {
        console.log(1);
	})
	.then(() => {
        console.log(2);
	})
	.then(() => {
        console.log(3);
	})
	.then(() => {
        console.log(5);
	})
	.then(() => {
        console.log(6);
	});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_45754783

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值