1.js数据类型有哪些
基本类型:字符串(String)、数字 (Number) 、布尔 (Boolean) 、空(Null)、未定义(Undefined)、Symbol(唯一值)
引用类型:对象(Object)、数组(Array)、函数(Function)、Set(ES6)、Map(ES6)
2.JavaScript内置对象有哪些
JS中内置了17个对象,常用的是 Array 对象、 Date 对象、 String 对象、Math 对象 、 Global 对象
Array对象中常用方法:
方法 | 参数 | 返回值 | 作用 | 是否改变原数组 |
---|---|---|---|---|
concat () | 要合并的其他数组,如:array2, array3, …, arrayX | 返回一个新数组,表示已连接的数组 | 将几个数组合并成一个数组 | 否 |
join () | 可选,指定要使用的分隔符(字符串),若不指定,默认的分隔符为逗号 | 返回一个由数组中的元素组成的并且以指定的分隔符分割的 字符串值 | 将数组转换为字符串 | 否 |
pop () | 无参数 | 返回移除的元素 | 移除数组中的最后一个元素 | 是 |
shift () | 无参数 | 返回移除的元素 | 移除数组中第一个元素 | 是 |
slice (start, end) | start 和 end 都是可选参数 ,并且可以是负数,表示从倒数第几个开始 / 至倒数第几个结束 | 返回一个新数组,包含从 start(包括该元素) 到 end (不包括该元素) 的 arrayObject 中的元素 | ①切割数组并且返回切割下来的片段 ②可提取字符串的某个部分,并以新的字符串返回被提取的部分。 | 否 |
splice(index,howmany,item1,…,itemX ) | ①index : 数组下标,必需。规定从何处添加/删除元素 ②howmany : 可选。规定应该删除多少元素。必须是数字,但可以是 “0”,如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素 ③ item1, …, itemX : 可选。要添加到数组的新元素 | 如果删除一个元素,则返回一个元素的数组; 如果未删除任何元素,则返回空数组 | 用于 添加或删除 数组中的元素 | 是 |
push () | item1, item2, …, itemX : 必需参数,指定要添加到数组末尾的元素 | 返回数组新长度(Number类型) | 向数组的末尾添加一个或多个元素,并返回新的长度 | 是 |
unshift () | item1, item2, …, itemX : 可选参数,指定要添加到数组开头的元素 | 返回数组新长度(Number类型) | 向数组的开头添加一个或更多元素,并返回新的长度 | 是 |
sort (sortfunction) | sortfunction : 可选参数,规定排序顺序。必须是函数。默认排序顺序为 按字母升序。如果对数字元素进行排序则必须通过一个函数作为参数来调用,否则40将排在5的前面 | 返回排序后的数组,请注意,数组在原数组上进行排序,不生成副本 | 用于对数组的元素进行排序 | 是 |
reverse () | 无参数 | 返回颠倒顺序后的数组 | 用于颠倒数组中元素的顺序 | 是 |
indexOf (item,start) | ① item : 必须参数,指定要查找的元素。② start : 可选的整数参数。规定在数组中开始检索的位置。如果省略,则从开头往后查询 | 返回指定元素在数组中 第一次出现 的索引,如果没有查询到此元素则返回 -1 | 从前往后查询指定元素的索引 | 否 |
lastIndexOf (item,start) | 同上,但是如果省略则从末尾开始往前查询 | 返回指定元素在数组中 最后一次出现 的索引,如果没有查询到此元素则返回 -1 | 从后往前查询指定元素的索引 | 否 |
Date对象
get/setFullYear():返回或设置年份,用四位数表示。
get/setYear():返回或设置年份,已废弃。
get/setMonth():返回或设置月份。0为一月
get/setDate():返回或设置日期。
getDay():返回一周中的周几。(没有setDay方法)
get/setHours():返回或设置小时,24小时制
get/setMinutes():返回或设置分钟数。
get/setSeconds():返回或设置秒钟数。
getTime() : 返回 1970 年 1 月 1 日至今的毫秒数。
setTime() : 向 1970年01月01日 添加或减去 xxx 毫秒
String对象
charAt () : 返回指定索引的位置的字符
concat ():拼接字符串,等效于加号,返回新字符串
replace (old,new) :字符 new 替换 old ,只替换首个匹配到的字符,参数也可以是正则表达式
replaceAll (old,new) :字符 new 替换 old ,替换所有匹配到的字符,参数也可以是正则表达式
search ():检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,返回其起始位置;如果没有找到匹配,则返回 -1。
slice (start,end):和数组中的 slice() 用法相同,返回字符段片段。不改变源字符串。
substring (start,end) : 取得指定字符串片段内的子字符串,返回的子串包括 开始 处的字符,但不包括 结束 处的字符。 不改变源字符串。
substr (start,length) :也是字符串截取 ,不改变源字符串;
substr() 的参数指定的是子串的开始位置和长度,因此它可以替代 substring() 和 slice() 来使用。
split () : 把字符串分割成字符串数组,如果参数是空字符串,则每一个字符都会作为一个元素。
split有两个参数:separator 和 limit,都是可选参数,separator可以为字符串或正则表达式,从该参数指定的地方分割 string Object;
limit参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
toUpperCase():把字符串转换为大写
toLowerCase():把字符串转换为小写
trim () : 用于删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符等
Math对象
Math.PI :圆周率属性
Math.abs():取绝对值
Math.min/Math.max () :求最小(大)值
Math.ceil():向上取整 ( 往大了取,0.1取为1,1.5取为2,-5.1 取为 -5 )
Math.floor():向下取整 ( 往小了取,0.1取为0,1.5取为1,-5.1 取为 -6 )
Math.round():四舍五入返回整数。
Math.random():返回介于 0(包含) ~ 1(不包含) 之间的一个随机数。
Math.sin() :返回数的正弦值
Math.cos() :返回数的余弦值
Math.sqrt() :返回数的平方根 ( Math.sqrt(81) => 9 )
Math.pow(a , b) : 返回 a 的 b 次幂(Math.pow(2 , 3) => 2的3次方 )
Global对象
是一个固有对象,目的是把所有的全局方法集中在一个对象中。
Global全局对象下的属性/函数没有语法,可以直接调用。
escape(): 对 String 对象编码以便它们能在所有计算机上可读.
escape(charString)
必选项 charstring 参数是要编码的任意 String 对象或文字。
isNaN() : 判断一个值是否为NaN,如果参数值为 NaN 或字符串、对象、undefined等非数字值则返回 true,否则返回 false
注意:null 进行 isNaN 判断返回值为false
- 全局 isNaN() 函数将测试值转换为数字,然后对其进行测试。
- Number.isNaN() 不会将值转换为数字,并且不会为任何非数字类型的值返回 true。
parseInt(string, radix):解析一个字符串,并返回一个整数,如果字符串的第一个字符不能被转换为数字,那么 parseInt() 会返回 NaN。
string参数:必需。指定要被解析的字符串。
radix参数:可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。
注意,当忽略参数 radix , JavaScript 默认数字的基数如下::
- 如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
- 如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
- 如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。
- 在字符串以 “0” 为开始时旧的浏览器默认使用八进制基数。ECMAScript 5,默认的是十进制的基数。
parseFloat() :解析一个字符串,并返回一个浮点数,如果字符串的第一个字符不能被转换为数字,那么 parseFloat() 会返回 NaN。
3.数组方法有哪些
此图截取自:简书
4.数组去重的几种方式
详情点这里
① 利用ES6 Set去重(ES6中最常用)
② 利用for嵌套for,然后splice去重(ES5中最常用)
③ 利用indexOf去重
④ 利用对象的属性不能相同的特点进行去重
⑤ 利用includes()方法(和indexOf相似)
⑥ 利用filter()方法
⑦ 利用hasOwnProperty()方法
5.数组深拷贝的几种方式
详情请点我
① 万能for循环
② 扩展运算符
③ concat()方法拼接空数组
④ slice()方法指定start为0,且不指定end
6.对象深拷贝的几种方式
详情也请点我
① 万能for循环
② 扩展运算符
③ 利用JSON左右互搏
④ Object.assign()方法
7.定时器有几种,有什么区别
JavaScript的定时器目前有三个: setTimeout 、 setInterval 和 setImmediate 。
setTimeout是一次性定时器,在设置的n毫秒延迟后执行一次就失效了;
setInterval是无限重复定时器,不用clearInterval清除定时器就会一直执行;
setImmediate这算一个比较新的定时器,目前IE11/Edge支持、Nodejs支持,Chrome不支持,其他浏览器未测试。
从API名字来看很容易联想到setTimeout(0),不过setImmediate应该算是setTimeout(0)的替代版。
在IE11/Edge中,setImmediate延迟可以在1ms以内,而setTimeout有最低4ms的延迟,所以setImmediate比setTimeout(0)更早执行回调函数。不过在Nodejs中,两者谁先执行都有可能,原因是Nodejs的事件循环和浏览器的略有差异。
setImmediate定时器的讲解转载自这里
8.谈一谈你对Promise的理解
摘自简书
Promise是为了解决Javascript回调嵌套过多导致回调地狱(callbackhell)而产生的。目前已被纳入了es2015(即ES6)规范,主流浏览器都支持Promise。
Promise的两个特点:
-
Promise对象的状态不受外界影响
1)pending 初始状态
2)fulfilled 成功状态
3)rejected 失败状态
Promise 有以上三种状态,只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这个状态
- Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可逆,只能由 pending 变成 fulfilled 或者由 pending 变成 rejected
Promise的三个缺点:
1)无法取消Promise,一旦新建它就会立即执行,无法中途取消
2)如果不设置回调函数,Promise内部抛出的错误,不会反映到外部
3)当处于pending状态时,无法得知目前进展到哪一个阶段,是刚刚开始还是即将完成
Promise的用法:
- Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
-
resolve 函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject 函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
-
Promise实例生成以后,可以用 then 方法分别指定 resolved 状态和 rejected 状态的回调函数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
Promise还有一个catch方法,专门用来处理操作异常后的业务。
9.谈一谈你对模块导入导出的理解
摘取自module的导入与导出
ES6在语言标准的层面上,实现了模块功能,成为浏览器和服务器通用的模块解决方案,完全可以取代 CommonJS 和 AMD 规范,基本特点如下:
-
每一个模块只加载一次, 每一个JS只执行一次, 如果下次再去加载同目录下同文件,直接从内存中读取;
-
每一个模块内声明的变量都是局部变量, 不会污染全局作用域;
-
模块内部的变量或者函数可以通过export导出;
-
一个模块可以导入别的模块
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能;
一个模块就是一个独立的文件,该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量;
var a = 123;
var b = "abc";
export {a,b};
👆 export 语法声明用于导出函数、对象、指定文件(或模块)的原始值。
有两种模块导出方式:命名式导出(名称导出)和默认导出(定义式导出),命名式导出每个模块可以有多个,而默认导出每个模块仅一个 。
-
命名式导出 : 模块可以通过export前缀关键词声明导出对象,导出对象可以是多个。这些导出对象用名称进行区分,称之为命名式导出;
export {fn1} // 导出已定义的fn1函数 export const foo = Math.sqrt(100) // 导出一个常量
我们可以使用 * 和 from 关键字来实现模块的继承:
export * from 'baseModule';//会把 baseModule 中所有的非default模块导出
模块导出时,我们可以使用as关键字对导出成员进行重命名:
export {name as bigName}
-
默认导出 :默认导出也被称做定义式导出。命名式导出可以导出多个值,但在import引用时,也要使用相同的名称来引用相应的值。默认导出只有导出一个单一值,这个输出可以是一个函数、类或其它类型的值,这样在模块import导入时也会更 容易引用。
export default function() {...}; export default class() {...};
import导入:
import语法声明用于从已导出的模块、脚本中导入函数、对象、指定文件(或模块)的原始值。
import模块导入与export模块导出功能相对应,也存在两种模块导入方式:命名式导入(名称导入)和默认导入(定义式导入)。
注意事项: import必须放在文件的最开始,且前面不允许有其他逻辑代码,这和其他所有编程语言的导入风格一致。
-
命名式导入:
export {fn1} // 导出已定义的fn1函数 import {fn1} from 'xxx'; // 导入已定义的fn1函数
-
默认导入:在模块导出时,可能会存在默认导出。同样的,在导入时可以使用import指令导入这些默认值。直接导入默认值:
import defaultName, {fn1,fn2} from 'xxx'; //指定成员导入和默认导入
通过*符号,我们可以导入模块中的全部属性和方法。当导入模块全部导出 内容时,就是将导出模块(’my-module.js’)所有的导出绑定内容,插入到当 前模块(’myModule’)的作用域中:
import * as myModule from 'my-module';
还有一种 require() 写法的导入方式,require/exports 是 CommonJS/AMD 中为了解决模块化语法而引入的;
require 是运行时调用,所以理论上可以运作在代码的任何地方
import 是编译时调用,所以必须放在文件的开头
此篇简书写的较为详细:JS中的import和require
10.箭头函数和普通函数的区别
-
外形(或者说定义方式)不同:箭头函数使用() => { } 定义,普通函数使用 function 关键字定义
-
箭头函数都是匿名函数; 普通函数可以匿名也可以具名
-
箭头函数没有prototype属性,所以箭头函数不能被用于构造函数
-
箭头函数中 this 的指向不同:
在普通函数中,this总是指向调用它的对象,如果用作构造函数,this指向创建的对象实例。
箭头函数的this指向它的上一级; -
call()、apply()方法不会改变箭头函数的this指向
-
箭头函数没有自己的 arguments(有arguments,但也是指向上一级)
11.JavaScript实现约瑟夫环问题
转自稀土掘金 ,里面还有两种方法
function countOff(num,m){
let players=[];
for(let i=1;i<=num;i++){
players.push(i);
}
let flag=0;
while(players.length>1){// 剩下一人,结束条件
let outPlayerNum=0,len=players.length;
for(let i=0;i<len;i++){
flag++;
if(flag===m){
flag=0;
console.log("出局:"+players[i-outPlayerNum]);
players.splice(i-outPlayerNum,1);
outPlayerNum++;
}
}
}
// return players[0];
console.log("剩下:"+players[0]);
}
// console.log("剩下:"+find(100,5))
countOff(100,5)
12.数组排序的几种写法
-
数组方法 sort()排序,基本用法:数组名.sort()
详细用法见文章:JavaScript 数组排序函数sort()的使用 -
冒泡排序(两层循环,两两互换)
//冒泡排序 function bubbleSort ( data ) { var temp = 0; for ( var i = data.length ; i > 0 ; i -- ){ for( var j = 0 ; j < i - 1 ; j++){ if( data[j] > data[j + 1] ){ temp = data[j]; data[j] = data [j+1]; data[j+1] = temp; } } } return data; }
更多方法见文章:数组排序的几种方法