js基础知识

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

js中存在着6种原始值,分别是:boolen,null,undefined,number,string,symbol(symobl是ES6引入了一种新的原始数据类型Symbol,表示独一无二的值)

 null 来说,很多人会认为他是个对象类型,其实这是错误的。虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象,然而 null 表示为全零,所以将它错误的判断为 object 。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。

2、对象类型和原始类型的不同之处?函数参数是对象会发生什么问题?

原始类型存储的是值。对象类型存储是的地址(指针),当你创建一个对象类型的时候计算机会在内存中开辟一个空间来存放值,但是我们需要找到这个空间,这空间会有一个地址(指针)

函数参数是对象,函数传参是传递对象指针的副本,函数参数会修改参数的属性,所以新的函数拥有了新的地址

3、typeof 是否能正确判断类型?instanceof 能正确判断对象的原理是什么?

typeof 对于原始类型来说除了NULL都可以显示正确的类型

typeof对于对象来说除了函数都会显示object,所以说typeof不能准确判断数据类型

如果我们想判断一个对象的正确类型,这时候可以考虑使用 instanceof,因为内部机制是通过原型链来判断的

对于原始类型来说,通过instanceof直接判断是不行的

4、js数据类型转换,熟悉了转换规则就不惧怕此类了

js类型转换只有三种情况分别是:转换为布尔值、转换为数字、转换为字符串

在判断时,除了unfinde\null\false\NAN\''\0\-0其所有转换为true,包括对象

对象在转换类型的时候,会调用内置[ToPrimitive]函数,对于函数来说算法逻辑一般如下:

如果已经时原始类型了,那就不需要转换。调用x.valueof(),如果转换为基础类型,就返回转换的值,调用x.toString(),如果转换为基础类型,就返回转换的值

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()

上面场景分析:

对于直接调用foo来说,不管foo函数被放在什么地方,this一定时window

对于obj.foo()来说,我们需要记住,谁调用了函数,谁就是this,所以在这个场景下foo函数中的this就是obj对象

对于new的方式来说,this被永远绑定在c上面,不会被任何方式改变this

首先箭头函数是没有this的,箭头函数中的this只取决于包裹箭头函数的第一个普通函数的this,如果第一个函数为空那么this就是window

6、== 和 === 有什么区别?

=是赋值,==是关系运算符,=== 是全等运算符(类型和值是否相等)

7、什么是闭包?

对于很多同学来说这个概念很乱晚上众说纷纭

function A() {

  let a = 1

  window.B = function () {

  console.log(a) } } A() B() // 1

闭包的定义其实很简单:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包。

在js中,闭包的存在意义就是让我们可以间接访问到函数内部的变量

循环中使用闭包解决 `var` 定义函数的问题

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

 

使用闭包的注意点

 

(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

 

(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

 

8、什么是浅拷贝?如何实现浅拷贝?什么是深拷贝?如何实现深拷贝?

浅拷贝: 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间.
注意:当内存销毁的时候,指向对象的指针,必须重新定义,才能使用,否则会出现野指针!

如何实现浅拷贝:let a = { age: 1 }

         let b = { ...a }

         a.age = 2

         console.log(b.age) // 1

 

 什么是深拷贝?

 

深拷贝是指copy的对象和被copy的对象两个都是独立的、互不影响的

。就像玩具厂生产出来的玩具,它们是一模一样的,都可以被买走,但是又是谁也不影响谁。

 

9、如何理解原型?如何理解原型链?

当我们创建一个对象时 let obj = { age: 25 },我们可以发现能使用很多种函数

其实每个 JS 对象都有 __proto__ 属性,这个属性指向了原型。

对于 obj 来说,可以通过 __proto__ 找到一个原型对象,在该对象中定义了很多函数让我们来使用

原型的 constructor 属性指向构造函数,构造函数又通过 prototype 属性指回原型,但是并不是所有函数都具有这个属性,Function.prototype.bind() 就没有这个属性。

其实原型链就是多个对象通过 __proto__ 的方式连接了起来。为什么 obj 可以访问到 valueOf 函数,就是因为 obj 通过原型链找到了 valueOf 函数。

10、什么是提升?什么是暂时性死区?var、let 及 const 区别?

什么时提升:console.log(a) // undefined

        var a = 1

虽然变量还没被声明,但是我们却可以使用这个未被声明的变量,这种情况就叫着提升,并且提升的时声明

var 、let 、const区别

var a = 1

let b = 1

const c = 1

console.log(window.b) // undefined

console.log(window. c) // undefined

首先在全局作用域下使用let和const声明变量,变量并不会被挂在到window上,这一点就和var声明的区别

var存在的提升,我们能在声明之前使用,let、const因为暂时性死区的原因,不能声明前使用

var在全局作用域下声明会导致变量挂载在window上,其它两者不会

let和const作用基本一致,但后者声明变量不能在次赋值

posted @ 2019-03-12 23:15  青松&  阅读(217)  评论(0编辑  收藏  举报