前端面试之路

「JavaScript」 基础知识要点及常考面试题(一)

2019-02-25  本文已影响0人  ybrelax

数据类型


原始类型有哪几种?null 是对象嘛?

typeof null 输出的Object,但是对于js来说它还是作为一个基本类型
typeof :
原始数据类型的判断采用 typeof ,
原理: 不同的对象在底层都表示为二进制, 在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0, 自然前三位也是 0, 所以执行 typeof 时会返回“object”。
instanceof:
引用数据类型的判断采用 instanceof
原理:通过原型链去判断

原始类型和对象类型的区别

原始类型存储的是值,对象类型存储的是一个地址

对象

for/in、Object.keys 和 Object.getOwnPropertyNames 对属性遍历有什么区别?你还知道其他遍历对象属性的方式吗?请说明。

ES6 一共有 5 种方法可以遍历对象的属性。

var parent = {}
Object.defineProperties(parent, {
    a: {
        value: 1,
        writable: true,
        enumerable: true,
        configurable: true
    },
    b: {
        value: 1,
        writable: true,
        enumerable: false,
        configurable: true
    },
    [Symbol('parent')]: {
        value: 1,
        writable: true,
        enumerable: true,
        configurable: true
    }
})
var child = Object.create(parent, {
    c: {
        value: 1,
        writable: true,
        enumerable: true,
        configurable: true
    },
    d: {
        value: 1,
        writable: false,
        enumerable: true,
        configurable: true
    },
    e: {
        value: 1,
        writable: true,
        enumerable: false,
        configurable: true
    },
    f: {
        value: 1,
        writable: true,
        enumerable: true,
        configurable: false
    },
    [Symbol('child')]: {
        value: 1,
        writable: true,
        enumerable: true,
        configurable: true
    }
})
  1. for...in
    for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
for (const key in child) {
    console.log(key)
}
// c d f a
  1. Object.keys(obj)
    Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
Object.keys(child)
// ["c", "d", "f"]
  1. Object.getOwnPropertyNames(obj)
    Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
Object.getOwnPropertyNames(child)
// ["c", "d", "e", "f"]
  1. Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols(child)
// [Symbol(child)]

Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

  1. Reflect.ownKeys(obj)
    Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
Reflect.ownKeys(child)
// ["c", "d", "e", "f", Symbol(child)]

类数组转换为数组有哪几种实现方式?

类数组对象:只包含使用从零开始,且自然递增的整数做键名,并且定义了length表示元素个数的对象,我们就认为他是类数组对象!

var obj = {
    0: 'a',
    1: 'b',
    length: 2
}
console.log(Array.from(obj))
console.log(Array.prototype.slice.call(obj))
console.log([].slice.call(obj))

字符串

常见的字符串方法

数组

常用的数组方法

数组常用方法.png

会改变原来数组的有:
pop()---删除数组的最后一个元素并返回删除的元素。

push()---向数组的末尾添加一个或更多元素,并返回新的长度。

shift()---删除并返回数组的第一个元素。

unshift()---向数组的开头添加一个或更多元素,并返回新的长度。

reverse()---反转数组的元素顺序。

sort()---对数组的元素进行排序。

splice()---用于插入、删除或替换数组的元素。

map 与 forEach的区别

let arr = [1, 2, 3, 4, 5];

arr.forEach((num, index) => {
    return arr[index] = num * 2;
});
// arr = [2, 4,6,8,10]
arr.map((num,index)=> {
  return num * 2;
})
// arr = [1, 2, 3, 4, 5];

this


如何正确的理解this

function foo() {
  console.log(this.a)
}
var a = 1
foo()

const obj = {
  a: 2,
  foo: foo
}
obj.foo()

const c = new foo()

分析:

  1. 在没有任何调用的情况, foo()的this是指向window
  2. obj.foo(), 谁调用this的指向就会指向谁
  3. new出来的对象,就绑定在c上
let a = {}
let fn = function () { console.log(this) }
fn.bind().bind(a)()

分析:
你们以为输出的结果是a?其实不然,bind函数所绑定都是由第一次绑定的值来决定,也就是fn.bind() => window

闭包


关于闭包的理解

闭包是指,函数中调用函数,函数A中有函数B的存在,函数B中调用函数A的变量。

function A() {
  let a = 1
  window.B = function () {
      console.log(a)
  }
}
A()
B() // 1

用途. 使用闭包去处理var关键字的问题

for (var i = 1; i <= 5; i++) {
  ;(function(j) {
    setTimeout(function timer() {
      console.log(j)
    }, j * 1000)
  })(i)
}

缺点:

  1. 由于闭包中的变量都是存储在内存中,所有很容易导致内存泄漏
  2. 闭包中会改变父级作用域的变量值,如果把父函数当作一个对象,闭包函数当作公有方法,那么里面的成员变量就要慎用,因为闭包函数会改变其父类的变量,从而影响其他的调用

深拷贝和浅拷贝

对于深拷贝和浅拷贝的理解

  1. 浅拷贝
    可以使用扩展运算符(...)
let a = {
  age: 1
}
let b = { ...a }
a.age = 2
console.log(b.age) // 1
  1. 深拷贝

原型链


原型链的一些要点

下面这张图展现了原型链的整个模型

原型链
推荐文章 原型链精选
上一篇 下一篇

猜你喜欢

热点阅读