检验你的Js基础 - 上

448 阅读6分钟

Part One

1.
function sayHi(){
    console.log(name)
    console.log(age)
    var name = 'Lydia'
    let age = 21
}
sayHi()

Result:
    undefined
    ReferenceError
2.
for(var i = 0;i<3;i++){
    setTimeout(()=>{
        console.log(i)
    },1)
}
for(let i = 0;i<3;i++){
    setTimeout(()=>{
        console.log(i)
    },1)
}

Result:
    3 3 3
    0 1 2
3.
const shape = {
    radius:10,
    diameter(){
        return this.radius * 2;
    },
    perimeter: () => 2 * Math.PI * this.radius
};
shape.diameter()
shape.perimeter() 

Result:
    20
    NaN
解析:箭头函数的this为其所在的上下文,此时指向window,没有radius属性
4.
+true;  // 1
!'Lydia' // false
5.
let c = {
    greeting:'Hey'
}
let d;
d = c;
c.greeting = 'Hello'
console.log(d.greeting)

Result:
    Hello
解析:对象的复制问题,复制的副本是地址
6.
let a = 3;
let b = new Number(3)
let c = 3
console.log(a == b) // true
console.log(a === b) // false
console.log(b === c) // false
7.
class ChameLeon{
    static colorChange(newColor){
        this.newColor = newColor;
    }
    constructor({newColor = 'green'} = {}){
        this.newColor = newColor
    }
}
const freddie = new ChameLeon({ newColor:'purple'});
freddie.colorChange('orange')

Result:
    TypeError
解析:colorChange方法是静态的,静态方法仅在创建它们的构造函数中存在,并且不能传递给任何子级,所以freddie实例上不存在changeColor方法
8.
let greeting;
greetign = {}; 
console.log(greetign); // {}

解析:
    控制台会输出空对象,因为我们刚刚在全局对象上创建了一个空对象!
    当我们错误地将greeting输入为greetign时,JS解释器实际上在浏览器中将其视为global.greetign = {}(或window.greetign = {})。
9.
function bark(){
    console.log('Woof!')
}
bark.animal = 'dog'

Result:
    这样做,什么都不会发生
    因为函数也是对象,所以可以为函数(对象)添加属性
10.
function Person(firstName,lastName){
    this.firstName = firstName
    this.lastName = lastName
}
const member = new Person('Lydia','Hallie');
Person.getFullName = () => this.firstName + this.lastName;
console.log(member.getFullName());

Result:
     TypeError : member.getFullName is not a function
     您不能像使用常规对象那样向构造函数添加属性。 如果要一次向所有对象添加功能,则必须使用原型。
     
Person.prototype.getFullName = function(){
    return `${this.firstName} ${this.lastName}`;
}
11.
function Person(firstName,lastName){
    this.firstName = firstName;
    this.lastName = lastName;
}
const lydia = new Person('Lydia','Hallie');
const sarah = Person('Sarah','Smith');
console.log(lydia) // Person {firstName: "Lydia", lastName: "Hallie"}
console.log(sarah) // undefined

解析:
    对于sarah,我们没有使用new关键字。 使用new时,它指的是我们创建的新空对象。 
    但是,如果你不添加new它指的是全局对象!
    
    我们指定了this.firstName等于'Sarah'和this.lastName等于'Smith'。 
    我们实际做的是定义global.firstName ='Sarah'和global.lastName ='Smith'。 
    sarah本身的返回值是undefined。
12.
事件传播的三个阶段
    捕获 - 目标 - 冒泡
13.
所有对象都有原型?
    除基础对象外,所有对象都有原型。(基础对象指原型链终点的对象。基础对象的原型是null。)
14.
function sum(a,b){
    return a + b;
}
sum(1,"2") // '12'

解析:
    强制转换,数字和字符串相加,数字转字符串 
15.
let number = 0
console.log(number++) // 0
console.log(++number) // 2
console.log(number) // 2
16.
function getPersonInfo(one,two,three){
    console.log(one);
    console.log(two);
    console.log(three)
}
const person = 'Ldyia'
const age = 21
getPersonInfo`${person} is ${age} years old`

Result:
    ["", "is", "years old"] Lydia 21
解析:
    如果使用标记的模板字符串,则第一个参数的值始终是字符串值的数组。 
    其余参数获取传递到模板字符串中的表达式的值!
17
function checkAge(data){
    if(data === { age:18 }){
        console.log('You are an adult')
    }else if(data == { age:18 }){
        console.log('You are still an adult')
    }else{
        console.log('you dont have an age I guess')
    }
}
checkAge({age:18}) // You dont have an age I guess

解析:
    我们作为参数传递的对象和我们用于检查相等性的对象在内存中位于不同位置,所以它们的引用是不同的
    这就是为什么{ age: 18 } === { age: 18 }和 { age: 18 } == { age: 18 } 返回 false的原因。
18.
function getAge(...args){
    console.log(typeof agrs);
}
getAge(21)  // object

解析:
    扩展运算符(... args)返回一个带参数的数组。 
    数组是一个对象,因此typeof args返回object。
    typeof不能精确判断是哪一类对象
19.
function getAge(){
    "use strict";
    age = 21;
    console.log(age);
}
getAge(); //ReferenceError
20.
const sum = eval('10 * 10 + 5'); // 105

解析:
    eval会为字符串传递的代码求值。 如果它是一个表达式,就像在这种情况下一样,它会计算表达式。 表达式为10 * 10 + 5计算得到105。
21.
var num = 8
var num = 10
console.log(num) // 10

解析:
    相同的名称声明多个变量,变量将保存最新值 (不能使用let / const来实现这一点)
22.
const obj = { 1:'a',2:'b',3:'c'}
const set = new Set([1,2,3,4,5])
obj.hasOwnProperty('1') // true
obj.hasOwnProperty(1) // true
set.has('1') // false  
set.has(1) // true

解析:
    所有对象键(不包括Symbols)都会被存储为字符串,即使你没有给定字符串类型的键。 
    这就是为什么obj.hasOwnProperty('1')也返回true
23.
const obj = { a:'one',b:'two',a:'three' }
console.log(obj) // { a:three,b:two }

解析:
    如果对象有两个具有相同名称的键,则将替前面的键。
    它仍将处于第一个位置,但具有最后指定的值。
24.
for(let i = 1;i < 5;i++){
    if(i == 3) continue;
    console.log(i)
} // 1 2 4    i == 3 时会跳过迭代
25.
String.prototype.giveLydiaPizza = () => {
    return 'Just give Lydia pizza already!'
};
const name = 'Lydia'
name.giveLydiaPizza(); // "Just give Lydia pizza already!"

为String类型添加方法(原型)
26.
const a = {}
const b = { key:'b' }
const c = { key:'c' }
a[b] = 123
a[c] = 456
console.log(a[b]) // 456

解析:
   当对象自动转换为字符串化时,它变成了[Object object]。 所以我们在这里说的是a["Object object"] = 123,
   然后,我们可以尝试再次做同样的事情。 c对象同样会发生隐式类型转换。那么,a["Object object"] = 456,
   然后我们打印a[b],实际上是a['Object object'],其设置为456 
27.
const foo = () => console.log('First')
const bar = () => setTimeout(() => console.log('Second'))
const baz = () => console.log('Third')
bar(); 
foo();
baz();

Result:
    First
    Third
    Second
解析:
    这里是事件循环的问题,遇到定时器时,定时器会挂起,等待当前这个宏任务执行完后才执行定时器
28.
const person = { name:'Lydia' };
function sayHi(age){
    console.log(`${this.name} is ${age}`)
}
sayHi.call(person,21)  // Lydia is 21
sayHi.bind(person,21) // function 

解析:
    bind不是立即执行,返回一个函数
29.
function sayHi(){
    return (() => 0)();
}
typeof sayHi(); // number

解析:
    sayHi函数返回立即调用的函数(IIFE)的返回值。 该函数返回0,类型为数字。
30.
console.log(typeof typeof 1) // string

解析:
    typeof 1 返回 "number".
    typeof "number" 返回 "string"
31.
const numbers = [1,2,3]
numbers[10] = 11
console.log(numbers) // [1, 2, 3, empty x 7 , 11]
32.
(() => {
    let x,y
    try{
        throw new Error()
    }catch(x){
        (x = 1),(y = 2)
        console.log(x)
    }
    console.log(x)
    console.log(y)
})();

Result:
    1
    undefined
    2
解析:
    catch块接收参数x。当我们传递参数时,这与变量的x不同。这个变量x是属于catch作用域的
    我们将这个块级作用域的变量设置为1,并设置变量y的值。 现在,我们打印块级作用域的变量x,它等于1
    在catch块之外,x仍然是undefined,而y是2
33.
!!null  // false
!!""    // false
!!1     // true
34.
setInterval(() => console.log('Hi'),1000)

返回值为一个唯一的id,用于clearInterval(id)
setTimeout也是如此
35.
var a = [...'Lydaia']; 
console.log(a)

Result:
    ['L','y','d','a','i','a']

扫码关注公众号,学习前端基础知识