【javaScript】- 笔试题合集(长期更新,建议收藏,目前已更新至31题)

本篇文章用于记录javaScript相关的一些题目,且长期更新,建议收藏!

1.使用原生js,通过addEventListener给每一个li元素绑定一个click事件,输出他们的顺序

js 复制代码
window.onload = function test() {
    var liList = document.getElementsByTagName("li");
    console.log(liList)
    for (var i = 0; i < liList.length; i++) {
        // 这里使用立即执行函数后,此时fun函数的[[scope]][0]=当前这个立即执行函数
        // 而每次for都会形成一个新的匿名函数,所以每个fun函数的[[scope]][0]是独一无二的,保存的i都为当前的i
        (function (j) {
            liList[j].addEventListener("click", function fun() {
                console.log(j)
            })
        }(i))
    }
}

2.写出以下打印信息

js 复制代码
a = 100;
function demo(e) {
    function e() { }
    arguments[0] = 2;
    console.log(e);//2
    if (a) {
        var b = 123;
        function c() {
            //猪都能做出来
        }
    }
    var c;
    a = 10;
    var a;
    console.log(b);//undefined
    f = 123;
    console.log(c);//以前打印的是function c(){};现在打印undefined
    console.log(a);//10
}
var a;
demo(1);
console.log(a);//100
console.log(f);//123

3.写一个方法,求一个字符串的字节长度(提示:字符串有一个方法charCodeAt(),一个中文占两个字节,一个英文占一个字节,当返回值是<=255 时,为英文,当返回值>255时为中文)

js 复制代码
function test(target) {
    var count = target.length;
    for (var i = 0; i < target.length; i++) {
        if (target[i].charCodeAt() > 255) {
            count++
        }

    }
    return count
}

4.写出以下打印信息

js 复制代码
// 4.
var f = (
    function f() {
        return "1"
    },
    function g() {
        return 2
    }
)()
// 首先明确一点,关于逗号计算符的使用:先看逗号前的表达式,如果要计算会进行计算;再看逗号后的表达式,如果要计算会进行计算,最后返回逗号后表达式的计算结果
// var f = (...)(),会先执行前一个括号的内容,其相当于一个表达式。()中有逗号运算符,执行逗号运算符的机制,会返回逗号后的内容,也就是g函数。
// 然后执行后面的括号,也就是执行符号,将g函数进行执行,会返回数字2,并赋值给f
console.log(typeof f)
// typeof f 相当于 typeof(2) 为"number"

5.写出以下打印信息

js 复制代码
var x = 1;
if (function f() { }) {
    x += typeof f
}
// if (function f() { }) = true,因为if括号中的内容当成一个表达式执行并将其转化为boolean值,f是个函数,所以为true,并且此时函数作为一个表达式执行了,被销毁了
// x += typeof f =》 x = x + typeof f = 1 + 'undefined' = '1undefined'。因为f此时是一个未被定义的变量,这种情况typeof f会返回"undefined"
console.log(x); //打印'1undefined'

6.使用递归实现n的阶乘

js 复制代码
//①抽象规律:n! = n * (n - 1)!  ②出口:n为1时,为1
function factorial(n) {
    if (n == 1) {
        return 1;
    }
    return n * factorial(n - 1)
}

7.使用递归实现斐波那契数列

js 复制代码
//①抽象规律:n = (n-1) + (n-2)  ②出口:n为1和2时,为1
function sequence(n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    return sequence(n - 1) + sequence(n - 2)
}

8.写出以下打印信息

js 复制代码
var str = false + 1; //+号,若两侧没有字符串,会致力于将其转化为数字进行计算,通过隐式调用Number实现。Number(false)+Number(1)=0+1=1
console.log(str); //打印1
var demo = false == 1; //赋值符号优先级最后,先看false == 1,==会致力于将两者转换为相同,通过隐式调用Number实现。Number(false)==Number(1),即0==1,得出值为false,并将值赋值给demo
console.log(demo); //打印false
//typeof (a):结果为"undefined"。因为是字符串的undefined,所以会继续往后看
//-true:结果为1。因为-会将其致力于转换为数字类型,通过隐式调用Number实现。Number(true)=1
//+undefined:结果为NaN。因为+会将其致力于转换为数字类型,通过隐式调用Number实现。Number(undefined)=NaN
//-true + (+undefined) + "":结果为"NaN",会进入判断。因为 1+NaN,+会致力于将其转化为数字进行计算,通过隐式调用Number实现,值为NaN,NaN+""。+一边有字符串,会致力于将其转化为字符串,进行拼接,所以='NaN'
if (typeof (a) && -true + (+undefined) + "") {
    console.log("1")//打印"1"
}
// *优先级高,先算"11" * 2,*会会致力于将其转化为数字进行计算,通过隐式调用Number实现。得值为22,所以11 + "11" * 2 = 11+22=33,会等于33,进入判断
if (11 + "11" * 2 == 33) {
    console.log("2")//打印"2"
}
//!!" "为true;!!"" 为false;!!false为false。则!!" " + !!"" - !!false 为1+0+0=1,为真,不继续往后看了
!!" " + !!"" - !!false || console.log("3")

9.写出以下打印信息

js 复制代码
// 1.全局预编译,得到GO:{glob:undefined,demo:undefined,a:function a(){...}},得到a.[[scope]][0]为GO:{...}
function a() {
    function b() {
        var bbb = 234;
        // 沿着作用域链从上往下找,先找第0位即bAO,没有则继续往下,找第1位aAO,返回123
        console.log(aaa);//123
    }
    // 4.将aaa修改为123。此时aAO:{aaa:123,b:function b(){...}}
    var aaa = 123;
    // 5.将b函数返回出去,并赋值给demo
    return b;
    // 6.a函数执行完毕,销毁a的执行期上下文,此时a.[[scope]][0]为GO:{...}
}
// 2.改变glob的值,此时GO:{glob:100,demo:undefined,a:function a(){...}}
var glob = 100;
// 3.执行a(),进行a函数的预编译,得到a.[[scope]][0]为aAO:{aaa:undefined,b:function b(){...}};a.[[scope]][1]为GO:{...}
// 得到b.[[scope]][0]为aAO:{...};a.[[scope]][1]为GO:{...}
var demo = a();
// 7.执行demo(),也就是执行b函数,进行b函数的预编译,得到b.[[scope]][0]为bAO:{bbb:undefined};b.[[scope]][1]为aAO:{...};b.[[scope]][2]为GO:{...}
demo();

10.写出以下打印信息

js 复制代码
// 1.全局预编译,得到GO:{demo:undefined,a:function a(){...}},得到a.[[scope]][0]为GO:{...}
function a() {
    // 3.将mum值赋值位100.此时aAO:{num:100,b:function b(){...}}
    var num = 100;
    function b() {
        // 7.将num值+1,沿着作用域链从上往下找,先找第0位即bAO,没有则继续往下,找第1位aAO,将mum的值重写为101
        // 11.将num值+1,沿着作用域链从上往下找,先找第0位即bAO,没有则继续往下,找第1位aAO,将mum的值重写为102
        num++;
        // 8.沿着作用域链从上往下找,先找第0位即bAO,没有则继续往下,找第1位aAO,返回101
        // 12.沿着作用域链从上往下找,先找第0位即bAO,没有则继续往下,找第1位aAO,返回102
        console.log(num);
        // 9.b函数执行完毕,销毁b的执行期上下文,此时b.[[scope]][0]为aAO:{...};a.[[scope]][1]为GO:{...}
        // 13.b函数执行完毕,销毁b的执行期上下文,此时b.[[scope]][0]为aAO:{...};a.[[scope]][1]为GO:{...}
    }
    // 4.将b函数返回出去,并赋值给demo
    return b;
    // 5.a函数执行完毕,销毁a的执行期上下文,此时a.[[scope]][0]为GO:{...}
}
// 2.执行a(),进行a函数的预编译,得到a.[[scope]][0]为aAO:{num:undefined,b:function b(){...}};a.[[scope]][1]为GO:{...}
// 得到b.[[scope]][0]为aAO:{...};a.[[scope]][1]为GO:{...}
var demo = a();
// 6.执行demo(),也就是执行b函数,进行b函数的预编译,得到b.[[scope]][0]为bAO:{};b.[[scope]][1]为aAO:{...};b.[[scope]][2]为GO:{...}
demo();
// 10.执行demo(),也就是执行b函数,进行b函数的预编译,得到b.[[scope]][0]为bAO:{};b.[[scope]][1]为aAO:{...};b.[[scope]][2]为GO:{...}
demo();

11.写出以下打印信息

js 复制代码
var x = 1, y = z = 0;
function add(n) {
    return n = n + 1;
}
y = add(x);
function add(n) {
    return n = n + 3;
}
z = add(x)
// 答案是x=1,y=x=4
// 因为有预编译环节,会将add函数提前放置到执行期上下文中,且只能有一个add属性名,且后面出现的会覆盖前面的函数声明
// 所以y和z调用的add都是后面一个add函数。都为4

12.下面代码中console.log()的结果是[1,2,3,4,5]的选项是?

js 复制代码
// A
function foo(x) {
    console.log(arguments);
}
foo(1, 2, 3, 4, 5);
// B 这种写法不报错也不输出,相当于把(1, 2, 3, 4, 5)这个当作一个表达式执行了,并不是当成方法调用
function foo(x) {
    console.log(arguments);
    return x
} (1, 2, 3, 4, 5);
// C
(function foo(x) {
    console.log(arguments);
    return x
})(1, 2, 3, 4, 5);
// D
function foo() {
    bar.apply(null, arguments)
}
function bar(x) {
    console.log(arguments)
}
foo(1, 2, 3, 4, 5);
// 答案是A、C、D

13.写出以下打印信息

js 复制代码
function employee(name, code) {
    // 这里使用this赋值是直接赋值的固定值,而不是传入的实参
    this.name = 'wangli';
    this.code = 'A001';
}
var newemp = new employee("zhangming", 'A002');
console.log("雇员姓名:" + newemp.name); // 雇员姓名:wangli
console.log("雇员代码:" + newemp.code); //雇员代码:A001

14.写出以下打印信息

js 复制代码
var str = 'abc';
str += 1;//str = str + 1 = 'abc' + 1 = 'abc1'
var test = typeof (str);// test = typeof('abc1') = 'string'
if (test.length == 6) { //test.length = 6 进入判断
    // String(test).sign = '...' 而后销毁该包装类
    test.sign = 'typeof的返回值可能为String';
}
// String(test).sign = undefined
console.log(test.sign) //undefined

15.写出以下打印信息

js 复制代码
function Person(name, age, sex) {
    var a = 0;
    this.name = name;
    this.age = age;
    this.sex = sex;
    function sss() {
        a++;
        console.log(a);
    }
    this.say = sss;
}
var oPerson = new Person();
// say是Person构造函数中的函数,形成了闭包,所以oPerson对象在调用say方法时,所使用的a是同一个
oPerson.say();//1
oPerson.say();//2
// 这里oPerson1和前面的oPerson不是同一个对象,是全新创建了一个对象,两者之间无任何联系
var oPerson1 = new Person();
oPerson1.say();//1

16.请问以下表达式的结果是什么?

js 复制代码
parseInt(3,8); // 3。以8为基地把3转为10进制的数,依旧为3
parseInt(3,2); // NaN。因为2进制没有3这个数,所以有误,返回结果为NaN
parseInt(3,0); // 3 或者 NaN。因为没有0进制。有些浏览器认为有误,返回NaN,有些则认为0进制那就是没有,直接忽略返回3

17.看看下面alert的结果是什么?

js 复制代码
function b(x, y, a) {
    arguments[2] = 10;
    alert(a);//10
}
b(1, 2, 3);
// 如果函数体改成下面,结果又会是什么?
a = 10;
alert(arguments[2]);//10
// 答案都是10,因为实参列表和形参是互相映射的,一个改了另一个也会跟着改。

18.写出以下打印信息

js 复制代码
var name = '222';
var a = {
    name: '111',
    say: function () {
        console.log(this.name)
    }
}
var fun = a.say;//相当于把a.say放到了fun上
fun();//fun在全局执行,this指向window,打印"222"
a.say();//this指向a,打印"111"
var b = {
    name: "333",
    say: function (fun) {
        fun();
    }
}
b.say(a.say);//b的say方法里的this指向的是b,此时里面的fun()是谁也没调用的情况,所以走的预编译环节,指向的是window,打印111
b.say = a.say;//将a的say方法放到b.say上
b.say();//执行b.say,b调用的,指向b,所以打印333

19.写出以下打印信息

js 复制代码
var foo = '123';
function print() {
    var foo = '456';
    this.foo = '789';
    console.log(foo);//456.会先在AO中找,找到foo为456,返回
}
print();

20.写出以下打印信息

js 复制代码
var foo = '123';
function print() {
    this.foo = '234';//print是在全局调用的,此时this会指向全局,所以会将全局的foo变成234
    console.log(foo);//234,会先在AO中找,AO中没有,则沿着作用域链找,找到全局foo为234,返回
}
print();

21.写出以下打印信息

js 复制代码
var foo = '123';
function print() {
    this.foo = '234';//此时print是通过new关键字调用的,所以此时this会指向隐式自己创建的this
    console.log(foo);//123,会先在AO中找,AO中没有,则沿着作用域链找,找到全局foo为123,返回
}
new print();

22.①运行test()和②new test()的结果分别是什么?

js 复制代码
var a = 5;
function test() {
    a = 0;
    alert(a);//①0  ②0
    alert(this.a);//5 ②undefined
    var a;
    alert(a)//①0 ②0
}

23.写出以下打印信息

js 复制代码
function print() {
    console.log(foo);//undefined
    var foo = 2;
    console.log(foo);//2
    console.log(hello);//报错
}
print();

24.写出以下打印信息

js 复制代码
function print() {
    var test;
    test();
    function test() {
        console.log(1);//1
    }
}
print();

25.写出以下打印信息

js 复制代码
function print(){
    var x = 1;
    if(x == '1')console.log("One!");//One!会尽量让两边相等,此时调用Number()将其都转为数字,所以相等,会打印
    if(x === '1')console.log("Two!");//不不打印.===要完全相等才行
}
print();

26.写出以下打印信息

js 复制代码
function print() {
    var marty = {
        name: "marty",
        printName: function () { console.log(this.name); }
    }
    var test1 = { name: "test1" };
    var test2 = { name: "test2" };
    var test3 = { name: "test3" };
    test3.printName = marty.printName;
    var printName2 = marty.printName.bind({ name: 123 });
    marty.printName.call(test1);//test1
    marty.printName.apply(test2);//test2
    marty.printName();//marty
    printName2();//123
    test3.printName();//test3
}
print()

27.写出以下打印信息

js 复制代码
var bar = { a: "002" };
function print() {
    // 将全局的bar.a修改为了a
    bar.a = 'a';
    Object.prototype.b = 'b';
    return function inner() {
        console.log(bar.a);//先找自身没有bar变量,沿着作用域链找上级print的AO也没有,再继续找到全局,发现有,返回a
        console.log(bar.b);//先找自身没有bar变量,沿着作用域链找上级print的AO也没有,再继续找到全局,发现有,但是没有b这个属性,则会沿着原型链往上找.找到原型链上有b返回b
    }
}
print()()
console.log(window.bar)

28.写出以下打印信息

js 复制代码
Person.prototype.name = 'hu';
function Person() {
    // new时会隐式调用:var this = {__proto__:Person.prototype}
}
Person.prototype = {
    name: "luo"
};
var person = new Person();
console.log(person.__proto__.name);// 打印luo
// 代码运行过程
// 1.预编译 GO:{person:undefined,Person:function Person(){}}
// 2.执行Person.prototype.name = 'hu'
// 3.执行Person.prototype = {name: "luo"};
// 4.执行person = new Person()。也就是说这时候才会发生将原型赋值给this中的__proto__属性
// 5.执行console.log(person.__proto__.name)。Person.prototype是后修改的那个,为luo

29.写出以下打印信息

js 复制代码
Person.prototype = {
    name: "a",
    sayName: function () {
        console.log(this.name);//a
        console.log(this);//a
    }
};
function Person() {
    // new时会隐式调用:var this = {__proto__:Person.prototype}
}
var person = new Person();
person.sayName()
Person.prototype.sayName();
// 代码运行过程
// 1.预编译 GO:{person:undefined,Person:function Person(){}}
// 2.执行Person.prototype = {...}
// 3.执行person = new Person()。会发生将原型赋值给this中的__proto__属性
// 4.执行person.sayName()。也就是会运行person原型链上的sayName方法,
// 5.执行console.log(this.name)。因为是person对象调用的方法,所以里面的this会指向该对象
//   而person本身并没有name属性,于是会沿着原型链找,找到其原型上有name为a,返回
// 6.执行Person.prototype.sayName()。因为是Person.prototype对象调用的方法,所以里面的this会指向该对象,返回name的值为a

30.写出以下打印信息

js 复制代码
Person.prototype = {
    height: 100
}
function Person() {
    // new时会隐式调用:var this = {__proto__:Person.prototype}
    this.eat = function () {
        this.height++;
    }
}
var person = new Person();
person.eat();
console.log(person);//{height:101,eat:function eat(){...}}
console.log(person.__proto__);//{height:100}
// 代码运行过程
// 1.预编译 GO:{person:undefined,Person:function Person(){}}
// 2.执行Person.prototype = {...}
// 3.执行person = new Person()。会发生将原型赋值给this中的__proto__属性
// 4.执行person.sayName()。也就是会运行person原型链上的sayName方法,
// 5.执行person.eat()。因为是person对象调用的方法,所以里面的this会指向该对象,
//   而person本身并没有height属性,于是会沿着原型链找,找到其原型上有height为100,取得该值并+1为101,
//   然后为自身创建一个height对象,值为101。也就是说原型上的height值不变,自身多了height属性为101
// 6.执行console.log(person)。打印person对象,为{height:101,eat:function eat(){...}}
// 7.执行console.log(person.__proto__)。打印person.__proto__对象,为{height:100}

31.以下哪些表达式的结果为true?

js 复制代码
// A
undefined == null;
// B
undefined === null;
// C
isNaN('100');//Number('100') = 100,是数字类型,不是NaN,所以为false
// D
parseInt('1a') == 1
// E
({}) == ({});//引用值比较的是地址,这是两个不同的对象,所以地址并不相等为false
// 答案是A、D
相关推荐
慌糖2 小时前
流-为序列化解释
开发语言
指尖跳动的光2 小时前
将多次提交合并成一次提交
前端·javascript
程序员码歌2 小时前
短思考第263天,每天复盘10分钟,胜过盲目努力一整年
android·前端·后端
oden2 小时前
1 小时速通!手把手教你从零搭建 Astro 博客并上线
前端
若梦plus2 小时前
JS之类型化数组
前端·javascript
若梦plus2 小时前
Canvas 深入解析:从基础到实战
前端·javascript
若梦plus2 小时前
Canvas渲染原理与浏览器图形管线
前端·javascript
LXS_3573 小时前
Day 18 C++提高 之 STL常用容器(string、vector、deque)
开发语言·c++·笔记·学习方法·改行学it