JavaScript面试那些事儿前端开发那些事儿

200道前端基础题及答案(上)

2020-12-03  本文已影响0人  深度剖析JavaScript
1.【关于函数参数】下面代码的执行结果是什么
function getInfo(member, year) {
    member.name = "Alice";
    year = "2020"
}
var person = { name: "Tom" }
var brithYear = "2010";
getInfo(person, brithYear);
console.log(person, brithYear);

答案:{name:Alice},2010

2.【Event Loop】下面代码的执行结果是什么
var p = new Promise(resolve => {
    console.log(4);
    resolve(5);
});
function func1() {
    console.log(1)
}
function func2() {
    setTimeout(() => {
        console.log(2)
    });
    func1();
    console.log(3);
    p.then(resolved => {
        console.log(resolved)
    }).then(() => {
        console.log(6)
    });
}
func2();

答案:4 1 3 5 6 2
解析:事件循环机制,主程序执行完,再执行微队列,再执行宏队列;Promise then会先进入微队列,setTimeout等进入宏队列

3.下面的代码的执行结果是什么
function Car(){
    this.name = "BMW"
    return {
        name:"maserati"
    }
}
var car = new Car();
console.log(car.name);

答案:maserati
解析:new构造函数产生对象时,有显示返回一个对象的情况,this就是该对象

4.模拟实现placeholder作用
<input type="text" name="user" value="请输入用户名" style="color:#999"
onfocus="if(this.value=='请输入用户名'){this.value = '';this.style.color='#424242'}"
onblur="if(this.value == ''){this.value = '请输入用户名';this.style.color='#999'}" >
5.下面代码的执行结果是什么
var a = 1;
var b = 2[a,b] = [b,a]
console.log(a,b)

答案:a是1,b是[undefined , 1]
解析:预编译和包装类对象的结果

6.下面代码最后打印arr是什么
var arr = [1,2,3,4,5];
arr.length = 1;

答案:[1]
解析:length会影响数组

7.下面代码执行结果是什么
var arr = [1+1,1*2,1/2];
console.log(arr);

答案:[2,2,0.5]
解析:数组保存的时候,每一位的表达式都会先运算

8.下面代码的执行结果是
var one = (false || {} || null);
var two = (null || false || "");
var three = ([] || 0 || true);
console.log(one,two,three);

答案:{},"",[]
解析:本题考查||运算符的用法。其实记住一条规律:||运算符返回的是能确认最终结果的值!

9.下面代码执行结果是?
var h5course = false;
var result = h5course / 0;
if (result) {
    console.log(result * 2 + '2' + 4)
} else {
    console.log(!result * 2 + '2' + '4')
}

答案:"224"
解析:0/0,null/0,undefined/0,false/0都为NaN,其他正数/0为infinity,其他负数除以0位-infinity。!NAN为true,true*2为2

10.下面代码执行结果是什么?
var a = 0, b=0;
function A(a){
    A = function(b){
        alert(a + b++)
    }
    alert(a++)
}
A(1)
A(2)

答案:1,4
解析:深入预编译和闭包就会得出结果

11.下面代码的执行结果是?
var str = new Array(5).toString()
console.log(str);

答案:",,,,"
解析:new Array(n) 返回的是以length为n、每一位为空的数组。
所以正因为new Array有这样那样的问题,一般推荐使用字面量如:var arr = [5]

12.下面代码的执行结果是什么?
console.log(123..toString());

答案:"123"
解析:包装类的原因,js会将123.通过new Number(123.)打包成包装类对象。调用的是Number.prototype.toString,所以new Number(123.).toString === Number.prototype.toString

13.下面代码的执行结果是?
var x = 1;
var y = 2;
function show() {
    var x = 3;
    return {
        x: x,
        fun: function (a, b) {
            x = a + b;
        }
    }
}
var obj = show();
obj.fun(x, y);
console.log(obj.x)
console.log(x)

答案:3,1
解析:考查知识点闭包和预编译

14. 下面的代码执行结果是?
var a = (true + false) > 2 + true;
console.log(a);

答案:false
解析:涉及知识点运算符的计算顺序和类型转换;
有()先算(),存在隐式类型转换true + false 变成1+0,
算数运算优先比较运算符,所以先算2+1
最后比较是:1>3 得出false

15.说说运算符的优先级

【小括号()】 > 【逻辑非!】 > 【算数*/%】> 【算数+-】> 【关系比较><==】 > 【逻辑与&&、逻辑或||】 > 【三目 ? :】 > 【赋值=】
大致是这样,具体可以查看这篇文档,里面有个表:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

16.下面代码执行结果是?
var num = 3;
console.log(num.toString(2));
console.log(num.toFixed(2));

答案:11、3.00
解析:toString方法传入一个参数时,表示把一个数当成10进制转成对应的进制的数,这里3被当成10进制,变成2进制就是11;而toFixed方法把目标数变成保留指定位数的小数,注意会四舍五入!这里保留两位小数,即变成3.00

17.下面代码的执行结果是什么?
function a(x){
    return x*2
}
var a;
console.log(a);

答案:function a(x){return x*2}

18.下面代码的运行结果是什么?
function fun(n, o) {
    console.log(o);
    return {
        fun: function (m) {
            return fun(m, n);
        }
    }
}
var a = fun(0);
a.fun(1);
a.fun(2);
a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(2);
c.fun(2);
c.fun(3);

答案:

undefined 0 0 0

undefined 0 1 2

undefined 0 2 2

19.下面代码的执行结果是?
var a = []+[]+"alice".split("");
console.log(a);

答案:"a,l,i,c,e"
解析:[]+[]为空字符串'',空字符串加数组,等于把数组变成字符串的形式,相当于数组调用了toString

20.有两个变量a和b,其值为number类型且非NaN,不借助其他变量,完成a与b的交换

答案:方式有很多种,下面是其中给一种
var a = 101;
var b = 102;
a = a + b;
b = a - b;
a = a - b;
console.log(a,b)

21.下面代码的执行结果是?
function Point(x, y) {
    this.x = x;
    this.y = y;
    this.moveTo = function (x, y) {
        this.x = x;
        this.y = y;
        console.log(this.x, this.y)
    }
}
var p1 = new Point(0, 0);
var p2 = { x: 0, y: 0 };
p1.moveTo(1, 1);
p1.moveTo.apply(p2, [10, 10])

答案:1,1 和 10,10
解析:this指向有两点,(1) 函数谁调用里面this指向谁,(2) apply call bind可改变函数执行时的this指向

22.下面代码的执行结果是什么?
var globalVar = 0;
(function (outerArg) {
    var outerVar = 456;
    (function (innerArg) {
        var innerVar = 10;
        console.log(globalVar, outerArg, outerVar, innerArg, innerVar);
    }(789))

}(123))

答案:0,123,456,789,10
解析:立即执行函数与普通函数执行没有区别

23.下面代码执行结果是什么?
console.log(1 + undefined);//NaN
console.log(1 + null);//1
console.log(null + undefined);//NaN 
console.log(true + false);//1
console.log(1 + '2');//12
console.log(2 + []);//2
console.log(2 + { a: 1 });//2[object Object]
console.log([] + {});//[object Object]
console.log({} + []);//[object Object]
console.log(3 + {});//3[object Object]
console.log({} + 3);//[object Object]3

答案:如上

解析:知识点加号运算符存在隐式类型转换,其中加对象时,相当于数值+"[object Object]",充当字符串连接符

24.下面代码的执行结果是什么?为什么
var a = {},b={key:"b"},c={key:'c'};
a[b] = 123;
a[c] = 456;
console.log(a[b]);

答案:456
解析:在设置对象的属性时,如果属性传入是一个对象,js会隐式的讲变量变成对象对应的[object Object]
所以:a[b]和a[c]其实都相当于a["[object Object]"],所以他们操作的都是a对象的同一个属性,因此结果为456

25.下面代码的执行结果是什么?
for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, i * 1000);
}

答案:5 5 5 5 5
解析:异步setTimeout是放在宏任务中,等执行完for循环之后再放到任务队列中执行
可以用let或者立即执行函数解决
方法一:
for(let i = 0;i<5;i++){
setTimeout(function(){
cosnole.log(i);
},i1000)
}
方法二:
for (var i = 0; i < 5; i++) {
(function(i){
setTimeout(() => {
console.log(i)//0 1 2 3 4
}, i
100);
}(i))
}

26.下面代码执行结果是?
var user = "Alice"
function changeUser(){
    user  = "Tom";
    return;
    function user(){
        console.log('user function')
    }
}
changeUser();
console.log(user);

答案:Alice

解析:原因很简答,在执行changeUser函数的时候,预编译将里头函数user提升了,后面改变user = "Tom",改变的是changeUser函数里面的局部变量。

27.下面代码执行的结果是什么?
(function(){
    var user = author = "Alice";
}());
console.log(author);
console.log(user);

答案:Alice、Uncaught ReferenceError: user is not defined

解析:全局里面没有user,所以访问时会报错。而author是暗示全局变量,是有值的。

28.下面代码的执行结果是?
console.log(0 || 1);
console.log(1 || 2);
console.log(0 && 1);
console.log(1 && 2);

答案是:1 1 0 2

解析:||或运算,前面为真,返回前面的,前面为false,返回后面的

&&与运算符 前面为假,返回前面的,前面为真,返回后面的

29.下面代码的执行结果是什么?
console.log(1 + '2' + '3');
console.log(1 + +'2' + '3');
console.log(1 + -'1' + '2');
console.log(+'1' + '2' + '3');
console.log('A' - 'B' + "2");
console.log("A" - "B" + 2);

答案:'123' '33' '02' '123' 'NaN2' NaN
解析:(1)任何数据类型+字符串都为字符串;(2)一元正负可以将其变成数值型;
(3)非数字类型或者非数字型字符串字符串相减,值为NaN

30.下面代码的执行结果是?
(function(){
    try{
        throw new Error
    }catch(x){
        console.log(x)//Error
        var x = 1;
        var y = 2;
        console.log(x)//1
    }
    console.log(x);//undefined
    console.log(y);//2
})();

答案: 1 undefined 2

解析:最开始执行匿名立即执行函数参数的作用域中,由于预编译将变量x和y提升了值为undefined

当执行catch函数时,里面有自己的形参变量x,这里的值是错误信息:Error,后面赋值为1;所以里面catch中先打印Error后打印1

y被赋值为2;

所以外面打印的值:x为undefined,y为改变的值2

31.下面代码的执行结果是?
var a = 10;
function fn() {
    console.log(this.a)
}
var obj = {
    a: 5,
    method: function (fn) {
        fn();//自己执行的,所有this指向window,打印出10
        arguments[0]();
    }
}
obj.method(fn, 1)

答案:10 undefined

解析:函数自己执行里面this指向window,

函数传入另外一个函数作为参数,通过arguments[0]的形式调用,相当于arguments.0(),arguments.0就代表该函数,所以里面this指向arguments。

再比如:

var length = 10;
function fn() {
    console.log(this.length)
}
var obj = {
    length: 5,
    method: function (fn) {
        fn();//自己执行的,所有this指向window,打印出10
        arguments[0]();//相当于arguments.0(),这里arguments的length为2,并且arguments.0中的0就是传入的fn,所以执行函数,相当于arguments调用。打印出2
    }
}
obj.method(fn, 1)

答案是:10 2

32.下面代码的执行结果
var fn = function a(){
    a = 1;
    console.log(typeof a)
}
fn();//function
console.log(typeof a)//undefined

答案:function undefined

解析:关于有名函数表达式需要注意2点:

(1)有名函数表达式的函数名(a)在函数体内还代表一个函数

(2)在函数体外部是会自动忽略函数的名称,即函数体外面是不能访问到(a)

(3)在函数体内部,函数名(a)不能再被修改

33.说说this和$(this)在jQuery中有什么不同?

答案:this是js关键字中的一个,表示当前DOM元素;而$(this)返回的一个jQuery对象,可以调用jQuery中封装的方法

34.下面代码的执行结果是什么?
function fn1() {
    return {
        str: 'hello'
    }
}
function fn2() {
    return
    {
        str: 'hello'
    }
}
console.log(fn1());
console.log(fn2());

答案:{str: "hello"} undefined
解析:js语言特性,如果语句表达是完整的,换行后默认会在语句后面加入‘;’

35.如何获取函数实参和形参的个数?

答案:

function fn(a,b){
    //1. 获取实参个数的方式:
    console.log(arguments.length);//5
    //2. 获取形参个数的方式:
    console.log(arguments.callee.length)//2
    arguments.callee===fn,所以也可以用fn.length获取形参个数
    console.log(fn.length)//2
}
fn(1,2,3,4,5);
36.下面代码执行结果是?
function Foo() {
    getName = function () {
        alert(1)
    }
    return this;
}
Foo.getName = function () {
    alert(2)
}
Foo.prototype.getName = function () {
    alert(3)
}
var getName = function () {
    alert(4)
}
function getName() {
    alert(5)
}
// 分析此时GO里有的东西:{
// getName: function getName() {alert(4)},
// Foo: function Foo(){getName = function () {alert(1)}  return this; }
// }
// 并且Foo的静态方法中有个Foo.getName = function () {alert(2)}
// 原型上还有个方法getName = function () {alert(3)}
// 下面的结果是?
Foo.getName();//2
getName()//4
Foo().getName()//Foo(),返回this为window,并且GO中的getName变成alert(1),所以这里是:1
getName()//1
new Foo.getName()//将Foo.getName函数作为构造函数执行,所以弹出:2
new Foo().getName();//调用的是原型上的方法 所以打印: 3
new new Foo().getName()//这里是js运算符的优先级问题,相当于new((new Foo()).getName)();答案输出:3

答案:如上

37.下面代码的执行结果是?
var user = 'alice';
function firstFn(){
    console.log(user);
}
function secondFn(){
    var user = 'tom';
    firstFn();
}
firstFn();

答案:'alice'

解析:变量查找是顺着作用域链查找的,例子中,secondFn的作用域没有加到firstFn,

需要注意的是,看是否有加入到某个作用域链中,主要是看该函数的定义位置,而不是使用位置。

38.如何阻止a标签的默认跳转事件?

答案:

let tagA = document.getElementsByTagName('a')[0]
taga.onclick = function (e) {
    //w3c
    // e.preventDefault();
    //IE独有的
    // e.returnValue = false;
    //都可以用
    return false;
}
39.如何让一个元素不显示

答案:

let odiv = document.getElementsByClassName("div")[0]
// 方法1
odiv.style.display = 'none'
// 方法2
odiv.style.visibility = "hidden"
// 方法3
odiv.styly.opacity = 0
40.下面代码的执行结果是?
let arr = [1, 2, 3, 4]
arr[10] = 10
arr[20] = 20
console.log(arr[15])

答案:undefined

解析:可以溢出读和写,溢出读时值为undefined,溢出写时,中间空位值为undefined

41.下面代码的执行结果是什么?
console.log(typeof undefined == typeof NULL)

答案:true

解析:js大小写敏感,NULL不是null,如果是typeof null返回的是object类型

42.下面代码的执行结果是
function fn(xx){
    this.x = xx
    return this
}
var x = fn(5)
var y = fn(10)
console.log(x.x)
console.log(y.x)

答案:undefined 10

解析:在fn(5)执行完,window.x === window;在fn(10)执行的时候,window.x = 10,window.y === window;

因此x.x其实就是new Number(10).x,所以打印出undefined,y.x其实就是window.x ,所以打印出10

43.下面代码的执行结果什么?
var x = 5;
function fn(x){
    x = 8
    console.log(x)
}
fn()
console.log(x)

答案:8、5

解析:fn打印的x是局部变量x,所以先打印8,外面打印全局window的x,所以打印出5

44.下面代码的执行结果是
(function(x){
    return (function(y){
        console.log(x)
    })(2);
})(1)

答案:1

解析:第一个立即执行函数执行的时候,ao上有个x值为1,然后return第二个立即执行函数执行,这里还能访问到x,所以打印出1

45.下面代码的输出结果是什么?
var result = (function f(n) {
    return (n > 1) ? n * f(n - 1) : n
})(10)
console.log(result)

答案:10的阶层,即3628800

46.下面代码的执行结果是什么,为什么?
function fn(){
    var a = b = {}
    a.name = 'alice'
    b.age = 10
    console.log(b.name,a.age)
}
console.log(typeof a)
console.log(typeof b)

答案:alice 10 undefined object

解析:引用值的赋值是地址,地址指向一个对象。暗示全局变量属于window所有

47.下面代码的执行结果是?
console.log(+true)
console.log(!'str')

答案:1,false

解析:一元正负默认隐式调用Number();!默认取反后调用Boolean(),即!'str'相当于Boolean('str')

48.下面代码的执行结果是?
function Person(firstName,lastName){
    this.firstName = firstName
    this.lastName = lastName
}
let p1 = new Person('Lewis','Carroll')
let p2 =  Person('Lewis','Carroll')
console.log(p1)
console.log(p2)

答案:Person{fristName: 'Lewis', lastName: 'Carroll'}, undefined

49.下面代码的执行结果是什么?
function show(){
    "use strict";
    // name = "alice";
    age = 12;
    // console.log(`${name}今年${age}岁了`)
}
show()

答案:严格模式下,变量必须声明后再赋值,否则ReferenceError

解析:经过测试发现,如果严格模式下变量没声明就赋值为字符串,居然不报错。暂时待进一步验证

50.下面代码的执行结果是?
(function(){
    console.log(1)
    setTimeout(() => {
        console.log(2)
    }, 1000);
    setTimeout(() => {
        console.log(3)
    }, 0);
    console.log(4)
})()

答案:1 4 3 2

解析:考查的是执行队列的问题

51.下面代码,当点击页面button时,event.target打印的是什么?
<div onclick="console.log('first div',event.target)">
    <div onclick="console.log('second div')">
        <button onclick="console.log('button')">click me!</button>
    </div>
</div>

答案:event.target打印的是--> <button onclick="console.log('button')">click me!</button>

解析:点击tutton时,由于事件冒泡会传递到父级元素触发相同事件。而event.target记录的是事件的目标源头

52.下面的代码执行结果是什么?
function checkAge(data) {
    if (data === { age: 18 }) {
        console.log('我今年18岁了')
    } else if (data == { age: 18 }) {
        console.log('我今年成年了')
    } else {
        console.log('emmm...')
    }
}
checkAge({ age: 18 })

答案:emmm...

解析:引用值对比的是地址

53.下面代码的执行结果是?
let count = 0
console.log(count++)
console.log(++count)
console.log(count)

答案:0 2 2

解析:考查++运算符,如果++在后,先执行语句再+1;如果++在前面,先将数进行+1 然后在执行语句

54.如何判断一个变量是数组
let arr = []
//方法1
arr.contructor === Array
//方法2
arr instanceof Array
//方法3
Array.isArray(arr)
55.数组中的push pop unshift shift分别有什么用途?

push方法:给数组末尾添加一位或多位,返回变化后的数组长度

pop方法 :给数组末尾移除一位,返回移除的元素

unshift :给数组前面添加一位或者多位,返回变化后的数组长度

shift :移除数组最前位,返回移除的元素

注意:以上方法都会改变原始数组

56.下面代码的执行结果是?
(function(){
    var x = y = 12 
})()
alert(y)

答案:12

解析:暗示全局变量,即变量未经声明就赋值,该变量属于window

57.下面代码的执行结果是什么?
var x = 'global'
function fn1(){
    console.log(x)
}
function fn2(){
    var x = 'fn2'
    fn1()
}
fn2();

答案:global

解析:作用域是静态的,不取决于函数执行位置,而是取决于函数定义所在位置。

58.下面代码的执行结果是?
var a = 1
var b = a
b++
console.log(a, b)

答案:1,2
解析:原始值赋值是值的拷贝

59.下面代码的执行结果是?
var a = [1,2,3,4]
var b = a;
a.push(5)
console.log(a,b)

答案:[1,2,3,4,5] [1,2,3,4,5]
解析:引用值的赋值是地址的拷贝,指向的是同一个空间

60.下面代码的执行结果是?
var x = 5;
function F(){
    x = 12;
    console.log(x);
    console.log(this.x);
    var x;
    console.log(x)
}
new F()

答案:12 undefined 12

解析:考点一 new关键字;考点二 预编译

61.下面代码的执行结果是什么?
var arr = [1,2,3,4]
delete arr[1]
console.log(arr.length)
delete arr[3]
console.log(arr.length)

答案:4 4
解析:此处delete会移除arr数组中的第1位数据,虽然删除后该位置为empty,但数组的length不会变

62.下面代码的执行结果是什么?
var res = (12).toFixed(2)
console.log(res)

答案:'12.00'
解析:涉及到数字和包装类知识。如果是12.toFixed(2)就报错,相当于12.xxx!

63.下面代码的执行结果是什么?
console.log(12 + '5')
console.log(12 - '5')

答案:125 7

解析:+号运算符中有一个数是字符串时,则加号作用是字符串连接。-号运算符会将两边通过Number()转成数字再进行减法操作

64.下面代码的执行结果是什么?
var a = new Array(3);
var b = [undefined,undefined,undefined];
var c = [null,null,null];
var d = [false,false,false];
var e = [0,0,0];
console.log(a.join('-'));
console.log(b.join('-'));
console.log(c.join('-'));
console.log(d.join('-'));
console.log(e.join('-'));

答案:

--

--

--

false-false-false

0-0-0

解析:数组的join方法会将数组成员安装指定字符连接;特别的,如果join中数组成员是null或者undefined就会当成空串

65.如何获取一个大于等于0且小于等于9的随机整数?
console.log(Math.floor(Math.random()*10))
66.下面代码的执行结果是什么?
function sum(a, b) {
    return a + b;
}
console.log(sum(1, '2'));

答案:"12"

解析:字符串拼接

67.哪些对象没有原型?

答案:(1)基础的顶层对象;(2)通过Object.create(null)创建的对象

68.下面代码的执行结果是什么?
var obj = {
  a: 1,
  b: 2,
  a: 3
}
console.log(obj)

答案:{a:3,b:2}

解析:非严格模式对象里头变量可重复,但会后面的会覆盖前面的

69.下面HTML代码的执行结果是什么?
<div onclick="console.log('div')">
    <button onclick="console.log('btn')">click me!!</button>
</div>

答案:btn div

解析:结构上非视觉上嵌套的元素存在事件冒泡功能,即从子元素冒泡向父元素

70.下面代码的执行结果是?
console.log(typeof typeof 12)

答案:'string'

解析:任意类型经过第一次typeof之后返回类型都是字符串

71.下面代码的执行结果是什么?
var arr = [1, 2, 3];
arr[10] = 4;
console.log(arr);

答案:[1, 2, 3, empty * 7, 4]

解析:数组可以溢出写,中间没有内容部分为空(empty),读取时值为undefined

72.下面代码的执行结果是什么?
String.prototype.showInfo = ()=>{
    return 'This is showInfo!'
}
let str = 'aaa';
let res = str.showInfo();
console.log(res);

答案:'This is showInfo!'

解析:包装类和原型

73.下面代码的执行结果是什么?
console.log(!!undefined)
console.log(!!null)
console.log(!!'')    
console.log(!!0)
console.log(!!1)

答案:false false false false true
解析:!!运算符用于将值变成布尔值

74.下面代码的执行结果是什么?
console.log(1>2>3);
console.log(3>2>1);
console.log(1<2<3);
console.log(3<2<1);

答案:false false true true
解析:比较运算符,按顺序从左往右比较,将前面的结果跟后一个比较,有数值会优先转成数字

75.下面代码的执行结果是什么?
let  arr = [1,2,3];
arr.unshift('a');
arr.push('b');
let newArrr = [4,...arr,5];
console.log(newArrr);

答案:[4,'a',1,2,3,'b',5]
解析:考查数组的基本使用,以及扩展运算符的基本使用

76.下面代码的执行结果是什么?
console.log('12'/0);
console.log(0/0);
console.log(true == 1);
console.log(NaN === NaN);

答案:infinity NaN true false
解析:考查运算符

77.下面代码的执行结果是什么?

let a = 1;
a = (++a, a++);
console.log(a);
a = (a++, ++a);
console.log(a);

答案:2 4

解析:考查++运算符和逗号运算符。

++在前就先++在执行该语句,++在后就先执行完该语句在++

逗号运算符,会返回逗号后面的结果,当然前面的语句也会执行

78.js中定义函数的几种方式:

(1) 函数声明

function fn1(){}

(2)函数表达式

let fn2 = function(){}

(3)通过Function构造函数

let fn3 = new Function('a','b','return a+ b')

Function最后一个参数表示函数体,其余参数作为形参

79.下面代码的执行结果是什么?
function Person(){}
console.log(Person.prototype === Function);
console.log(Person.prototype === Function.prototype);
console.log(Person.__proto__ === Function.prototype);
console.log(new Person().__proto__ === Person.prototype);

答案:false false true true

解析:关于原型。原型是function对象的属性,它定义了构造函数构造出对象的共有祖先

80.下面代码的执行结果是什么?
function f(){
    f = 12;
    console.log(f);
}
console.log(f);
f();
console.log(f);

答案:f(){} 12 12
解析:暗示全局变量

81.下面代码的执行结果是什么?
var fn = (function(temp){
    arguments[0] = 'Hello';
    return function(){
        console.log(temp,arguments[0])
    }
})('Mike')
fn('Alice');

答案:Hello,Alice
解析:考查立即执行函数,以及形参与arguments相互映射

82.下面代码的执行结果是什么?
if(function fn(){}){
    console.log(typeof fn)
}
console.log(typeof fn)

答案:'undefined' 'undefined'

解析:在if语句的小括号中,js会自动将里面的东西通过Boolean()变成对应的布尔值,所以里头函数声明并不能再其他地方使用该函数

83.下面代码的执行结果是什么?
console.log(1..toString())
console.log(NaN.toString())
console.log(typeof temp) 
console.log(1 ++)

答案:前三个分别是:'1' 'NaN' 'undefined';

但最后一个语法有误:Uncaught SyntaxError: Invalid left-hand side expression in postfix operation

解析:由于js执行的时候会先扫一遍看有没有语法错误,然后在一行一行的执行js语句。如果语法有误时,并不会执行其他语句。所以这里会出现SyntaxError

84.说说call和apply函数

(1)call和apply都是Function.prototype上定义的函数,任何一个函数都有call和apply方法

(2)当函数调用和call或apply方法时,call和apply会改变函数里头的this指向,然后执行该函数

(3)call和apply唯一不同在于传参形式,

call第一个参数是this指向,第二个开始分别对应函数的参数,

apply第一个参数也是this指向,第二个参数是数组,数组里头分别对应形参

(4)另外与call和apply相似的函数,bind()。该函数只是绑定函数的this指向,不会立即执行该函数。

85.下面代码的执行结果是什么?
var obj = {
    name: 'obj'
}
var bar = {
    name:'bar',
    show:function(){
        var name = 'foo'
        console.log(this.name)
    }
}
bar.show.call(obj);

答案:'obj'

86.下面代码的执行结果是什么?
var val = 1
var fn = function(){
    var val = 2;
    return function(){
        console.log(this.val)
        console.log(val)
    }
}
fn()()

答案:1 2
解析:fn()执行返回function(){},然后再执行,执行时里面this为window,所以this.val是1,val是局部变量val为2

87.下面代码执行结果是什么?
var a = function () {
    this.b = 2;
}
a.prototype.b = 20;
b = new a();
console.log(b.b);
var b = 1000;
a();
console.log(this.b)

答案:2,2

解析:b被new出来的时候,里面自己保存了一个b,所以不用去原型上找,即第一个b.b打印出2

当a()执行的时候,由于里面this指向window,所以执行了window.b=2;所以最后全局答应this.b就是window.b,即打印出2

88.下面代码的执行结果是什么?
var a = { n: 1 }
var b = a
a.m = a = { m: 2 }
console.log(a)
console.log(b)

答案:a为{m:2},b为{n:1,m:{m:2}}
解析:这题需要特别注意,在js在读取a.m = a = { m: 2 }的时候,是从左往右;执行赋值是从右往左的。
所以先开始a和b指向的空间{n:1}变成{n:1,m:{m:2}},而a被重新赋值为{m:2},所以最终解雇结果a为{m:2},b为{n:1,m:{m:2}}

89.下面代码的执行结果是什么?
function Foo(){}
var f1 = new Foo()
console.log(f1.constructor)
Foo.prototype = {}
var f2 = new Foo()
console.log(f2.constructor)

答案:Foo(){}, Object(){}
解析:需要注意constructor是定义在原型上的东西,所以它会先找到自己的原型,然后再看constructor指向谁。
因此,在没改变原型前new出来的实例f1的constructor指向Foo,改变构造函数的原型后再new出来的对象f2的constructor就是Object(){}

90.下面代码的执行结果是什么?
function Person(){
    this.name = 'alice'
    return true;
}
var p = new Person();
console.log(p)

答案:Person {name: "alice"}

解析:构造函数构造对象时,如果构造函数本身显示return 原始值,会自动忽略,任然返回构造出来的this,如果显示返回引用值,那么this会被覆盖

91.下面代码的执行结果是什么?
var val = 1;
val.length = 2;
console.log(val.length)

答案:undefined
解析:调用原始类型的什么属性,其实是js内部将原始值变成包装类对象,执行完之后删除该对象。所以val.length为undefined

92.下面代码的执行结果是什么
var fn = function a(){
    console.log(a)
    a = 1;
    console.log(a)
}
fn();
console.log(a)

答案:function a(){...} function a(){...} Uncaught ReferenceError: a is not defined
解析:具名函数表达式的特点,函数名可以在函数内部访问,但是无法被修改。

93.下面代码的执行结果是什么?
function a() {
    console.log(1)
}
function b() {
    console.log(2)
}
function c() {
    console.log(3)
}
function d() {
    console.log(4)
}
false && a();//&&前面为false后面不会再看,所以这里不执行a()
true || b();//||前面为true后面不会再看,所以这里不执行b()
false || c();//||前面为false后面会再看,所以这里执行c(),打印出3
true && d();//&&前面为true后面会再看,所以这里执行d(),打印出4

答案:3 4

解析:主要&&和||运算符的特点,原则是根据前面的真假值来判断是否还要执行后面的表达式

94.下面代码的执行结果是什么?
function fn(a){
    let a = 10;
    console.log(a)
}
fn(1)

答案:Uncaught SyntaxError: Identifier 'a' has already been declared
解析:函数内,用let或者const声明的变量,不能与形参名相同,否则会报错

95.下面代码的执行结果是什么?
function fn1(){
    var a = 1;
}
function fn2(){
    return;
}
console.log(fn1(),fn2())

答案:undefined undefined
解析:没有返回的函数,默认返回undefined;只写return的就相当于没写返回,也是undefined

96.手写圣杯继承
var inherit = (function () {
    function F() { };
    return function (Target, Origin) {
        F.prototype = Origin.prototype;
        Target.prototype = new F();
        Target.prototype.constructor = Target;
        Target.prototype._super = Origin.prototype;
    }
}());
97.封装一个函数mul,用于计算n的阶层
function mul(n){
    if(n==0||n==1){
        return 1;
    }
    return n*arguments.callee(n-1);
}
98.封装一个函数bytesLengh,用于查找任意字符串的字节长度
function bytesLengh(str) {
    var count = str.length;
    for (var i = 0; i < str.length; i++) {
        if (str.charCodeAt(i) > 255){
            count++;
        }
    }
    return count;
}
charCodeAt(n):返回字符串第n位字符的unicode编码,大于255字节长度为2,小于为1
99.封装一个方法insertAfter,功能类似insertBefore
Element.prototype.insertAfter = function (targetNode, afterNode) {
    var beforeNode = afterNode.nextElementSibling;
    if (beforeNode) {
        this.appendChild(targetNode);
    }
    this.insertBefore(targetNode, beforeNode);
}
100.手动封装异步加载js的方法asyncLoadScript
function asyncLoadScript(url, callback) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    if (script.readyState) {//readyState是IE中的状态码
        script.onreadystatechange = function () {
            //绑定监听状态码的事件,IE状态码变成complete或者loaded,表示该元素加载完
            if (script.readyState == "complete" || script.readyState == "loaded") {
                callback();//回调函数,当script加载完后调用
            }
        }
    } else {
        //非IE 用onload事件,表示当script加载完时
        script.onload = function () {
            callback();//回调函数,当script加载完后调用
        }
    }
    script.src = url;//放在这,是为了避免IE立即加载完,立即加载完就不再触发onreadystatechange
    document.head.appendChild(script);//加载到页面中去
}
//=============test code=========================
asyncLoadScript('./js/tools.js', function () {
    //code
    console.log('按照加载完了:' + url + '文件')
});

文章转载自Duing,如需转载请联系Duing(ID:duyi-duing)

注:

上一篇下一篇

猜你喜欢

热点阅读