javascript面试题

本文深入探讨了JavaScript的基本数据类型、复杂数据类型、内置对象、闭包、原型链、同源策略等核心概念,以及代码规范、NaN处理、进制表示等实用技巧。

1 介绍js的基本数据类型

js一共有六种基本数据类型,分别是Undefined、Null、Boolean、Number、String,还有在ES6中新增的Symbol类型,代表创建后独一无二且不可改变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突的问题:
在这里插入图片描述

2 JavaScript有几种类型的值?

涉及知识点:

  • 栈:原始数据类型(Undefined,Null,Boolean、Number、String)
  • 堆:引用数据对象(对象、数组和函数)

1 两种类型的区别是:存储位置不同
2 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定、属于被频繁使用数据,所以放入栈中存储。
3 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的其实地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

回答
js可以分为两种数据类型,一种是基本数据类型,一种是复杂数据类型。

基本数据类…(参考1)

复杂数据类型值得是Object类型,所有其他的如Array、Date等数据类型可以理解为Object类型的子类。

两种类型的主要区别是他们的存储位置不同,基本数据类型的值直接保存在栈中,而复杂数据类型的值保存在堆中,通过使用在栈中保存对应的指针来获取堆中的值

3 内部属性[[Class]]是什么?

所有typeof返回值为"object"的对象(如数组)都包含一个内部属性[[Class]] (我们可以把它看作一个内部的分类,而非传统的面向对象意义上的类)。这个属性无法直接访问,一般通过 Object.prototype.toString(…) 来查看。例如:
在这里插入图片描述

4 介绍js有哪些内置对象

涉及到的知识点

全局的对象(global objects)或称标准内置对象,不要和 “全局对象(global object)” 混淆。这里说的全局的对象是说在全局作用域里的对象。全局作用域中的其他对象可以由用户的脚本创建或由宿主程序提供
标准内置对象的分类
(1)值属性,这些全局属性返回一个简单值,这些值没有自己的属性和方法
例如 Infinity、NaN、undefined、null 字面量
(2)函数属性,全局函数可以直接调用,不需要在调用时指定所属对象,执行结束后会将结果直接返回给调用者
例如 eval()、parseFloat()、parseInt() 等
(3)基本对象,基本对象是定义或使用其他对象的基础。基本对象包括一般对象、函数对象和错误对象
例如 Object、Function、Boolean、Symbol、Error 等
(4)数字和日期对象,用来表示数字、日期和执行数学计算的对象。
例如 Number、Math、Date
(5)字符串,用来表示和操作字符串的对象
例如 String、RegExp
(6)可索引的集合对象,这些对象表示按照索引值来排序的数据集合,包括数组和类型数组,以及类数组结构的对象
例如 Array
(7)使用键的集合对象,这些集合对象在存储数据时会使用到键,支持按照插入顺序来迭代元素
例如 Map、Set、WeakMap、WeakSet
(8) 矢量集合,SIMD矢量集合中的数据会被组织为一个数据序列
例如 SIMD 等
(9)结构化数据,这些对象用来表示和操作结构化的缓冲区数据,或使用JSON编码的数据
例如 JSON 等
(10)控制抽象对象
例如 Promise、Generator 等
(11)反射
例如 Reflect、Proxy
(12)国际化,为了支持多语言处理而加入 ECMAScript 的对象。
例如 Intl、Intl.Collator 等
(13)WebAssembly
例如 arguments

答案
js 中的内置对象主要指的是在程序执行前存在全局作用域里的由 js 定义的一些全局值属性、函数和用来实例化其他对象的构造函数对象。一般我们经常用到的如全局变量值 NaN、undefined,全局函数如 parseInt()、parseFloat() 用来实例化对象的构造函数如 Date、Object 等,还有提供数学计算的单体内置对象如 Math 对象。

5 undefined和undeclared的区别?

已在作用域中声明但还没有赋值的变量,是undefined。相反,还没有在作用域中声明过的变量,是undeclared

var a;
//已声明,没有赋值
console.log(a);//undefined
//是undefined
console.log(b); 
//没有声明,就引用浏览器回报Uncaught ReferenceError: b is not defined这个错
console.log(typeof(b));//undefined
//用typeof可以避免报错

6 说几条写 JavaScript 的基本规范?

在平常项目开发中,我们遵守一些这样的基本规范,比如说:
(1)一个函数作用域中所有的变量声明应该尽量提到函数首部,用一个 var 声明,不允许出现两个连续的 var 声明,声明时 如果变量没有值,应该给该变量赋值对应类型的初始值,便于他人阅读代码时,能够一目了然的知道变量对应的类型值。
(2)代码中出现地址、时间等字符串时需要使用常量代替。
(3)在进行比较的时候吧,尽量使用’=’, '!‘代替’==’, ‘!=’。
(4)不要在内置对象的原型上添加方法,如 Array, Date。
(5)switch 语句必须带有 default 分支。
(6)for 循环必须使用大括号。
(7)if 语句必须使用大括号。

7 js获取原型的方法?

  • p.proto
  • p.constructor.prototype
  • Object.getPrototypeOf§

8 在 js 中不同进制数字的表示方式

  • 以 0X、0x 开头的表示为十六进制。
  • 以 0、0O、0o 开头的表示为八进制。
  • 以 0B、0b 开头的表示为二进制格式。

9 typeof NaN的结果是什么?

NaN (not a number 非数字),它是一个警戒值,用于指出数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果”。

 console.log(typeof NaN);//number
 console.log(NaN===NaN);//false
 //NaN与自身不相等,唯一的非自反的值

10 isNaN和Number.isNaN函数的区别

函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。
函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,这种方法对于 NaN 的判断更为准确。

console.log(isNaN("abc"));//true
console.log(Number.isNaN("abc"));//false

11 {}和[]的valueOf和toString的结果是什么?

 console.log({}.valueOf()); //{}
 console.log({}.toString());//"[object Object]"    
 console.log([].valueOf());//[]     
 console.log([].toString());// ""

12 ~操作符的作用?

~ 返回 2 的补码,并且 ~ 会将数字转换为32位整数,因此我们可以使用 ~ 来进行取整操作。

 console.log(~2);//-3    console.log(~2.339988554422);//-3

13 [“1”, “2”, “3”].map(parseInt) 答案是多少?

parseInt() 函数能解析一个字符串,并返回一个整数,需要两个参数 (val, radix),其中 radix 表示要解析的数字的基数。(该值介于 2 ~ 36 之间,并且字符串中的数字不能大于 radix 才能正确返回数字结果值)。

此处 map 传了 3 个参数 (element, index, array),默认第三个参数被忽略掉,因此三次传入的参数分别为 “1-0”, “2-1”, “3-2”
因为字符串的值不能大于基数,因此后面两次调用均失败,返回 NaN ,第一次基数为 0 ,按十进制解析返回 1。

 console.log(["1", "2", "3"].map(parseInt));//[1, NaN, NaN]

14 闭包是什么,为什么要用它?

闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量。

闭包有两个常用的用途。

闭包的第一个用途是使我们在函数外部能够访问到函数内部的变量。通过使用闭包,我们可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量。

函数的另一个用途是使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收。

其实闭包的本质就是作用域链的一个特殊的应用,只要了解了作用域链的创建过程,就能够理解闭包的实现原理。

15 简单谈一下 cookie ?

我的理解是 cookie 是服务器提供的一种用于维护会话状态信息的数据,通过服务器发送到浏览器,浏览器保存在本地,当下一次有同源的请求时,将保存的 cookie 值添加到请求头部,发送给服务端。这可以用来实现记录用户登录状态等功能。cookie 一般可以存储 4k 大小的数据,并且只能够被同源的网页所共享访问。
服务器端可以使用 Set-Cookie 的响应头部来配置 cookie 信息。一条cookie 包括了5个属性值 expires、domain、path、secure、HttpOnly。其中 expires 指定了 cookie 失效的时间,domain 是域名、path是路径,domain 和 path 一起限制了 cookie 能够被哪些 url 访问。secure 规定了 cookie 只能在确保安全的情况下传输,HttpOnly 规定了这个 cookie 只能被服务器访问,不能使用 js 脚本访问。
在发生 xhr 的跨域请求的时候,即使是同源下的 cookie,也不会被自动添加到请求头部,除非显示地规定。

16 javascript 代码中的 “use strict”; 是什么意思 ? 使用它区别是什么?

use strict 是一种 ECMAscript5 添加的(严格)运行模式,这种模式使得 Javascript 在更严格的条件下运行。
设立"严格模式"的目的,主要有以下几个:

  • 消除JavaScript语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的一些不安分之处,保证代码运行的安全。
  • 提高编译器效率,增加运行速度
  • 为未来新版本的JavaScript做好铺垫

区别:

  • 禁止使用with语句
  • 禁止this关键字指向全局队形
  • 对象不能有重名的属性

回答:
use strict 指的是严格运行模式,在这种模式对 js 的使用添加了一些限制。比如说禁止 this 指向全局对象,还有禁止使用 with 语句等。设立严格模式的目的,主要是为了消除代码使用中的一些不安全的使用方式,也是为了消除 js 语法本身的一些不合理的地方,以此来减少一些运行时的怪异的行为。同时使用严格运行模式也能够提高编译的效率,从而提高代码的运行速度。我认为严格模式代表了 js 一种更合理、更安全、更严谨的发展方向。

17 instanceof的作用

// instanceof 运算符用于判断构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。
// 实现:
function myInstanceof(left, right) {
	let proto = Object.getPrototypeOf(left),
   	// 获取对象的原型    prototype = right.prototype; 
   	// 获取构造函数的 prototype 对象
  	// 判断构造函数的 prototype 对象是否在对象的原型链上 
   	while (true) {   
    		if (!proto) return false;   
     		if (proto === prototype) return true;
   		 proto = Object.getPrototypeOf(proto); 
     	}
    }

18 new 操作符具体干了什么呢?如何实现?

// (1)首先创建了一个新的空对象
// (2)设置原型,将对象的原型设置为函数的 prototype 对象
// (3)让函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性)
// (4)判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。
// 实现:
function objectFactory() {  
	let newObject = null,    
	constructor = Array.prototype.shift.call(arguments),    
	result = null;
  	// 参数判断  
  	if (typeof constructor !== "function") {    
  		console.error("type error");    
 		 return;  
  	}
  	// 新建一个空对象,对象的原型为构造函数的 prototype 对象  
  	newObject = Object.create(constructor.prototype);
  	// 将 this 指向新建对象,并执行函数  result = constructor.apply(newObject, arguments);
  	// 判断返回对象  let flag =    result && (typeof result === "object" || typeof result === "function");
  	// 判断返回结果  return flag ? result : newObject;}
	// 使用方法// objectFactory(构造函数, 初始化参数);

19 Javascript 中,有一个函数,执行时对象查找时,永远不会去查找原型,这个函数是?

hasOwnProperty

所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。这个方法可以用来检测一个对象是否含有特定的自身属性,和in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。

20 什么是浏览器的同源政策?

我对浏览器的同源政策的理解是,一个域下的 js 脚本在未经允许的情况下,不能够访问另一个域的内容。这里的同源的指的是两个域的协议、域名、端口号必须相同,否则则不属于同一个域。

同源政策主要限制了三个方面

第一个是当前域下的 js 脚本不能够访问其他域下的 cookie、localStorage 和 indexDB。

第二个是当前域下的 js 脚本不能够操作访问操作其他域下的 DOM。

第三个是当前域下 ajax 无法发送跨域请求。

同源政策的目的主要是为了保证用户的信息安全,它只是对 js 脚本的一种限制,并不是对浏览器的限制,对于一般的 img、或者script 脚本请求都不会有跨域的限制,这是因为这些操作都不会通过响应结果来进行可能出现安全问题的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值