Js面试题

103 阅读4分钟

1.对象创建几种方式

1.const obj1 = {name:'kobe',age:24};

2.const obj2 = Object({name:'kobe',age:24})

3.const obj3 = new Object({name:'kobe',age:24})

4.const obj4 = Object.create({name:'kobe',age:24})

//第1、第2、第3三种方式仅是书写方式不同,创造出的对象是一样
//obj.__proto__ === Object.prototype为true

//第4种方式则不同,它创造出的对象的原型不直接指向Object.prototype,obj4.__proto__ === {name:'kobe',age:24}为true,
//obj4.__proto__.__proto__ === Object.prototype为true

2.增强for循环

//1.js中的增强for循环一般指for of,用于迭代具有[Symbol.iterator]接口的类型数据,遍历获取的是value

// Array.prototype[Symbol.iterator] === ƒ values() { [native code] }
// Set.prototype[Symbol.iterator] === ƒ values() { [native code] }
// Map.prototype[Symbol.iterator] === ƒ values() { [native code] }

// 以Array为例
const arr = [10,20,30];
for(const val of arr){
   console.log(val);
}

//2.for in是js为方便遍历对象,特意创造出来的,遍历获取的是key,因Array是一种特殊的对象,固可以使用for in遍历,key也为Array的下标index

Object.prototype[Symbol.iterator] === undefined
const obj = {name:'kobe',age:24}
for(const key in obj){
  console.log(key+'=>'+obj[key]);
}

const arr = [10,20,30];
for(const key in arr){
  console.log(key+'=>'+arr[key]);
}

//3.给Object添加[Symbol.iterator]接口,使之能被for of遍历
//方式一
Object.prototype[Symbol.iterator] = function*(){
  const obj = this;
  const values = Object.values(obj);
  for(let i = 0;i < values.length;i++){
    yield values[i];
  }
}
const obj = {name:'kobe',age:24};
for(const val of obj){
  console.log(val);
}

//方式二
const obj = {name:'kobe',age:24};
obj[Symbol.iterator] = function(){
  const obj = this;
  const values = Object.values(obj);
  const len = values.length;
  let i = -1;
  return {
    next:function(){
      i++;
      if(i<len){
        return {value:values[i],done:false};
      }else{
        return {value:undefined,done:true};
      }
    }
  }
}
for(const val of obj){
  console.log(val);
}

3.闭包

//百度前端闭包,文章繁多,每一篇都是洋洋洒洒一大篇,感觉还没有说到重点,哪需那么多言语,不才在下说说自己的理解

//1.闭包是什么?一言以闭之,函数的定义和执行不在同一个作用域
  
//2.为什么会产生闭包
//  a.函数的执行会创建一个函数栈,执行完毕函数栈销毁
//  b.因为返回内部函数对外部函数的变量有引用,所有外部函数不销毁
//  c.js中变量的作用域在变量定义的时候已确定的,执行时根据已定作用域查找
  
//3.闭包的实际运用,redux中闭包的体现

function createStore (reducer, initialState, enhancer) {
      let currentState = initialState;
      let listeners = [];
      function dispatch (action) {
        currentState = reducer(action);
        for(let i = 0;i < listeners.length;i++){
          listeners[i]();
        }
      }
      function subscribe (listener) {
        return listeners.push(listener);
      }
      function getState () {
        return currentState;
      }
      function replaceReducer (newReducer) {
        reducer = newReducer;
      }
      return {
        dispatch: dispatch,
        subscribe: subscribe,
        getState: getState,
        replaceReducer: replaceReducer
      }
    }

4.原型链

//1.对象有隐式原型__proto__,指向其构造函数的prototype
//2.函数有显式原型prototype默认为{constructor:函数},因函数同时亦为对象所以有隐式原型__proto__指向Function.prototype
//3.Function.__proto__指向Function自己,Function.prototype指向Function
//4.Object.__proto__指向Function.prototype,Object.prototype.__proto__为null

5.作用域

//ES5使用var定义变量,只有全局和函数作用域
//ES6增加了let、const,对应增加了快级作用域

for(var i = 0;i < 10;i++){
  setTimeout(()=>console.log(i))
}

for(let i = 0;i < 10;i++){
  setTimeout(()=>console.log(i))
}


//变量查找采用就近原则,先在当前作用域查找,未找到向上级作用域查找,一直查找到顶层(即全局作用域),未找到报错
function fn(){
  const name = "KOBE";
  function tt(){
    const age = 30;
    console.log(`${name}今年${age}岁了`);
  }
  tt();
}
fn();

6.this指向

//function函数,谁触发this是谁,全局作用域下调用function this为window
//类似setTimeout这种自执行函数,this为window
//箭头函数,无this,里面的this为就近作用域的this

7.js加载

js load.png

<script> js的下载、执行都阻赛html解析
<script defer> js下载与html解析并行,html解析完后执行js
<script async> js下载与html解析并行,js下载完后即执行同时阻赛html解析

8.常用es6

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // Map
    const map = new Map([
      ["key1",123],
      ["key2",456],
    ])
    map.forEach(function(value,key){
      console.log(key,value);
    })
    const obj = Object.fromEntries(map)
    console.log(obj);

    //Set
    const set = new Set(["a","a","b","c"]);
    set.forEach(function(value){
      console.log(value);
    })
    const array = Array.from(set);
    console.log(array);

    //Symbol
    const ID1 = Symbol("id");
    const ID2 = Symbol("id");
    console.log(ID1,ID2,ID1===ID2);
    const t1 = Symbol.for("t");
    const t2 = Symbol.for("t");
    console.log(t1,t2,t1===t2);

    //class
    class Student{
      static getTime(){
        return `${this.name}/${Date.now()}`
      }
      constructor(name){
        this.name = name;
      }
      setAge(age){
        this.age = age;
      }
      setSex(sex){
        this.sex = sex;
      }
      getInfo(){
        return `${this.name}/${this.age}/${this.sex}`;
      }
    }
    const student = new Student("kobe");
    student.setAge(24);
    student.setSex("男");
    console.log(student.getInfo());
    console.log(Student.getTime());
    console.log(student);

    //proxy
    const obj1 = {name:"kobe"};
    const proxy = new Proxy(obj1,{
      get:function(target,property){
        return target[property]
      },
      set:function(target,property,value){
        target[property] = value;
      }
    })
    proxy.age = 24;
    console.log(proxy.name,proxy.age,proxy,obj1);

    //Reflect
    //https://www.cnblogs.com/windrunnermax/p/14030532.html

    //Generator
    function* generator(){
      yield 'one';
      yield 'two';
      return 'done';
    }
    const g = generator();
    console.log(g.next());
    console.log(g.next());
    console.log(g.next());
    console.log(g.next());

    //Promise
    //略

    //async awit
    async function fn(){
      async function getResult(){
        const result = await new Promise((resolve,reject)=>resolve("123"))
        return result;
      }
      const t = await getResult();
      console.log(t);
    }
    fn();

  </script>
</body>
</html>

ArrayBuffer: Blob.png