面试宝典 | JavaScript 基础

6 篇文章 0 订阅
1 篇文章 0 订阅

目录

一、数据类型

1、 JavaScript 的基本类型有哪些?引用类型有哪些?null 和 undefined 的区别?(必会)

2、如何判断 JavaScript 的数据类型?(必会)

问题一:typeof 不能识别 null,如何识别 null

问题二:typeof 作用于未定义的变量,会报错吗?

问题三:typeof Number(1)的返回值是什么?

问题四:typeof new Number(1)的返回值是什么?(p37)

问题5 instanceof

3、=== 和 ==的区别?(必会)

4、null,undefined 的区别(必会)

5、JavaScript 中什么情况下会返回 undefined 值?(必会)

6、列举三种强制类型转换和两种隐式类型转换?(必会)

7、判断一个值是什么类型有哪些方法?(必会) 

二、数组

1、多维数组降维的几种方法(必会)

2、什么是类数组(伪数组),如何将其转化为真实的数组?(必会) 

3、如何实现数组的随机排序?(必会) 

三、函数

1、简述创建函数的几种方式? (必会) 

7、src 和 href 的区别是?(了解)

三、对象

1、Javascript 创建对象的几种方式? (必会)

2、请指出 JavaScript 宿主对象和原生对象的区别?(必会)

3、JavaScript 内置的常用对象有哪些?并列举该对象常用的方法? (必会)

对象及方法

Array 数组

 String 字符串对象

Boolean 布尔对象

Date 日期时间

Error 异常对象

Function 函数构造器

Math 数学对象

Number 数值对象

Object 基础对象

RegExp 正则表达式对象

3、如何区分数组和对象?(必会)

4、怎么判断两个对象相等?(必会)

5、JavaScript 中怎么获取当前日期的月份?(必会)

6、如何遍历对象的属性?(必会)

7、如何使用原生 JavaScript 给一个按钮绑定两个 onclick 事件?(必会)

8、JavaScript 中的作用域、预解析与变量声明提升? (必会)

9、变量提升与函数提升的区别?(必会)

10、什么是作用域链?如何延长作用域链?(必会)


一、数据类型

1、 JavaScript 的基本类型有哪些?引用类型有哪些?null 和 undefined 的区别?(必会)

1 数据类型

基本数据类型:Number、String、Boolean、null、undefined

引用数据类型:Object、Function、Array?

2 区别

  • undefined:表示变量已声明但未初始化时的值。(未赋值)
  • null:表示准备用来保存对象,还没有真正保存对象的值。(赋空值,占个位)
    • 从逻辑角度看,null 值表示一个空对象指针

ECMA 标准要求 null 和 undefined 等值判断返回 true

  • null == undefined // true
  • null === undefined // false

2、如何判断 JavaScript 的数据类型?(必会)

判断方法

typeof typeof 可以用来区分除null 类型以外的原始数据类型,对象类型的可以从普通对象里面识别出函数?:

  • typeof 1 // "number"
  • typeof "1" // "string"
  • typeof undefined // "undefined"
  • typeof null // "object"
  • typeof Symbol() // "symbol"
  • typeof function() {} // "function"
  • typeof {} // "object

问题一:typeof 不能识别 null,如何识别 null

答案:如果想要判断是否为 null,可以直接使用===全等运算符来判断

(或者使用下面 的 Object.prototype.toString 方法)?:

let a = null
a === null // true

问题二:typeof 作用于未定义的变量,会报错吗?

答案:不会报错,返回"undefined"。

 typeof random Variable // "undefined"

问题三:typeof Number(1)的返回值是什么?

答案:"number"。

注意 Number 和 String 作为普通函数调用的时候,是把参数转化为相应的原始数据类型,也就是类似于做一个强制类型转换的操作,而不是默认当做构造函数调用。

注意和 Array 区分,Array(...)等价于 new Array(...)

  • typeof Number(1) // "number"
  • typeof String("1") // "string"
  • Array(1, 2, 3) // 等价于 new Array(1, 2, 3)

问题四:typeof new Number(1)的返回值是什么?(p37)

        答案:"object"。

typeof new Number(1) // "object"

typeof new String(1) // "object"

问题5 instanceof

-instanceof 不能用于判断原始数据类型的数据:

3 instanceof Number // false
'3' instanceof String // false
true instanceof Boolean // false

-instanceof 可以用来判断对象的类型:

var date = new Date()
date instanceof Date // true

var number = new Number()
number instanceof Number // true

var string = new String()
string instanceof String // true

-需要注意的是,instanceof 的结果并不一定是可靠的,因为在 ECMAScript7 规范中可以通过自定义 Symbol.hasInstance 方法来覆盖默认行为。

Object.prototype.toString
Object.prototype.toString.call(undefined).slice(8, -1) // "Undefined"
Object.prototype.toString.call(null).slice(8, -1) // "Null"
Object.prototype.toString.call(3).slice(8, -1) // "Number"
Object.prototype.toString.call(new Number(3)).slice(8, -1) // "Number"
Object.prototype.toString.call(true).slice(8, -1) // "Boolean"
Object.prototype.toString.call('3').slice(8, -1) // "String"
Object.prototype.toString.call(Symbol()).slice(8, -1)

-由上面的示例可知,该方法没有办法区分数字类型和数字对象类型,同理还有字符串类型 和字符串对象类型、布尔类型和布尔对象类型

-另外,ECMAScript7 规范定义了符号 Symbol.toStringTag,你可以通过这个符号自定义 Object.prototype.toString 方法的行为:

'use strict'
var number = new Number(3) 
number[Symbol.toStringTag] = 'Custom' 
Object.prototype.toString.call(number).slice(8, -1) // "Custom" 

function a () {} 
a[Symbol.toStringTag] = 'Custom' 
Object.prototype.toString.call(a).slice(8, -1) // "Custom" 

var array = [] 
array[Symbol.toStringTag] = 'Custom' 
Object.prototype.toString.call(array).slice(8, -1) // "Custom" 

因为 Object.prototype.toString 方法可以通过 Symbol.toStringTag 属性来覆盖默认行为,所以使用这个方法来判断数据类型也不一定是可靠的

  • Array.isArray
  • Array.isArray(value)可以用来判断 value 是否是数组:
Array.isArray([]) // true 
Array.isArray({}) // false 
(function () {console.log(Array.isArray(arguments))}()) // false

3、=== 和 ==的区别?(必会)

  • ===:  三个等号称为等同符,当等号两边的值为相同类型的时候,直接比较等号两边的值,值相同则返回 true,若等号两边的值类型不同时直接返回 false。
  •  ==:两个等号称为等值符,当等号两边的值为相同类型时比较值是否相同,类型不同时会发生类型的自动转换,转换为相同的类型后再作比较。

也就是说:

  • 三个等号既要判断值也要判断类型是否相等(both)
  • 两个等号只要值相等就可以(值)

4、null,undefined 的区别(必会)

null 表示一个对象被定义了,值为“空值”; undefined 表示不存在这个值

◆typeof undefined //"undefined"

undefined :是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但还没有定义。当尝试读取时会返回 undefined;

例如变量被声明了,但没有赋值时,就等于 undefined

-典型用法是:

  1. 变量被声明了,但没有赋值时,就等于 undefined (变量声明未赋值)
  2. 调用函数时,应该提供的参数没有提供,该参数等于 undefined (函数实参少于形参)
  3. 函数没有返回值时,默认返回 undefined (函数无return)
  4. 对象没有赋值的属性,该属性的值为 undefined

◆typeof null //"object"

null : 是一个对象(空对象, 没有任何属性和方法);表示"没有对象",即该处不应该有值。

例如作为函数的参数,表示该函数的参数不是对象;

注意: 在验证 null 时,一定要使用=== ,因为 == 无法分别 null 和 undefined  (见2-问题一)

典型用法是:

  1. 作为函数的参数,表示该函数的参数不是对象
  2. 作为对象原型链的终点

5、JavaScript 中什么情况下会返回 undefined 值?(必会)

1 访问声明,但是没有初始化的变量

let aaa; 
console.log(aaa); // undefined

2 访问不存在的属性

let aaa = {};  
console.log(aaa.c);

3 访问函数的参数没有被显式的传递值 (无实参)

 (function (b){ 
    console.log(b); // undefined 
})();

4 访问任何被设置为 undefined 值的变量

var aaa = undefined;
console.log(aaa); // undefined

5 无return或return无值

①没有定义 return 的函数隐式返回

function aaa(){}
console.log(aaa()); // undefined

 ②函数 return 没有显式的返回任何内容

function aaa(){ 
    return; }

console.log(aaa()); // undefined

6、列举三种强制类型转换和两种隐式类型转换?(必会)

强制

  • 转化成字符串 toString() String()
  • 转换成数字 Number()、 parseInt()、 parseFloat( 
  • 转换成布尔类型 Boolean()

隐式?

  • 拼接字符串
  • 例子
    let str = "" + 18  //String
    - * / %  //Number
    ==  //同类型转换

7、判断一个值是什么类型有哪些方法?(必会) 


二、数组

1、多维数组降维的几种方法(必会)

(1)数组字符串化

let arr = [[222, 333, 444], [55, 66, 77] ] 
arr += ''; 
arr = arr.split(','); 

console.log(arr); // ["222", "333", "444", "55", "66", "77"]

(2)递归

function reduceDimension(arr){
    let ret = []; 
    let toArr = function(arr){ 
        arr.forEach(function(item){
            item instanceof Array ? toArr(item) : ret.push(item); 
        }); 
    }

    toArr(arr); 
    return ret; 
}

 (3)Array .prototype .flat()

var arr1 = [1, 2, [3, 4]]; 
arr1.flat(); // [1, 2, 3, 4] 

var arr2 = [1, 2, [3, 4, [5, 6]]]; 
arr2.flat(); // [1, 2, 3, 4, [5, 6]] 

var arr3 = [1, 2, [3, 4, [5, 6]]]; 
arr3.flat(2); // [1, 2, 3, 4, 5, 6]

//使用 Infinity 作为深度,展开任意深度的嵌套数组
arr3.flat(Infinity); // [1, 2, 3, 4, 5, 6]

(4)使用 stack 无限反嵌套多层嵌套数组

var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]]; 
function flatten(input) { 
    const stack = [...input]; 
    const res = []; 
    while (stack.length) {
        // 使用 pop 从 stack 中取出并移除值
        const next = stack.pop(); 

        if (Array.isArray(next)) {
            // 使用 push 送回内层数组中的元素,不会改动原始输入 
            original input stack.push(...next); 
        } 
        else {
            res.push(next); 
        }
       }
       // 使用 reverse 恢复原数组的顺序
       return res.reverse(); 
    }

flatten(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]

(5)使用 reduce、concat 和递归无限反嵌套多层嵌套的数组

var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]]; 
function flattenDeep(arr1) { 
    return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []); 
} 

flattenDeep(arr1); // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]

2、什么是类数组(伪数组),如何将其转化为真实的数组?(必会) 

伪数组

伪数组(类数组):无法直接调用数组方法或期望 length 属性有什么特殊的行为,不具有数组的 push.pop 等方法,但仍可以对真正数据遍历方法来遍历它们。典型的是函数 document.childnodes 之类的,它们返回的 nodeList 对象都属于伪数组

1、具有 length 属性

2、按索引方式存储数据

3、不具有数组的 push.pop 等方法

伪数组-->真实数组

1.使用 Arrray.from()--ES6

2. [].slice.call(eleArr) 或则 Array.prototype.slice.call(eleArr)
示例:


let eleArr = document.querySelectorAll('li'); 
Array.from(eleArr).forEach(function(item){ 
    alert(item); 
}); 

let eleArr = document.querySelectorAll('li'); 
    [].slice.call(eleArr).forEach(function(item){ 
    alert(item); 
});

3、如何实现数组的随机排序?(必会) 


三、函数

1、简述创建函数的几种方式? (必会) 

第一种(函数声明):

function sum1(num1,num2){ 
    return num1+num2; 
}

第二种(函数表达式-匿名函数):

let sum2 = function(num1,num2){ 
    return num1+num2; 
} 

第三种(函数对象方式):

let sum3 = new Function(
    "num1","num2","return num1+num2"
);

7、src 和 href 的区别是?(了解)

src(source)

  • 指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置
  • 在请求 src 资源时会将其指向的资源下载并应用到文档中,如 JavaScript 脚本,img 图片 和 iframe 等元素
  • 当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,类似于将所指向资源嵌入当前标签内(首要)

href(hypertext reference/超文本引用)

  • 指向网络资源所在位置,建立和当前元素(锚点)或 当前文档(链接)之间的链接,如果我们在文档中添加
    <link href="common.css"rel="stylesheet"/>
    那么浏览器会识别该文档为 CSS 文件,就会并行下载资源并且不会停止对当前文档的处理(并行)

三、对象

1、Javascript 创建对象的几种方式? (必会)

1、简单对象的创建 使用对象字面量的方式{}

创建一个对象(最简单,好理解,推荐使用),代码如下

var Cat = {}; //JSON 

Cat.name="kity"; //添加属性并赋值 
Cat.age=2; 
Cat.sayHello=function(){ 
    alert("hello "+Cat.name+",今年"+Cat["age"]+"岁了"); //可以使用“.”的方式访问属性, 也可以使用 HashMap 的方式访问 
} 

Cat.sayHello(); //调用对象的(方法)函数

2、用 function(函数)来模拟 class

2.1) 创建一个对象,相当于 new 一个类的实例(无参构造函数) 代码如下 ?

function Person(){ }
var personOne=new Person(); //定义一个 function,如果有 new 关键字去"实例化",那么该 function 可以看作是一个类 

personOne.name="dylan"; 
personOne.hobby="coding"; 
personOne.work=function(){ 
    alert(personOne.name+" is coding now..."); 
} 
personOne.work();

2.2)可以使用有参构造函数来实现,这样定义更方便,扩展性更强(推荐使用) 代码如下

function Pet(name,age,hobby){ 
    this.name=name;//this 作用域:当前对象 
    this.age=age; 
    this.hobby=hobby; 
    this.eat=function(){ 
        alert("我叫"+this.name+",我喜欢"+this.hobby+",也是个吃货"); 
} }

    var maidou =new Pet("麦兜",5,"睡觉");//实例化/创建对象 
    maidou.eat();//调用 eat 方法(函数

3、使用工厂方式来创建(Object 关键字) 代码如下:

var wcDog = new Object(); 
wcDog.name="旺财"; 
wcDog.age=3; 
wcDog.work=function(){ 
    alert("我是"+wcDog.name+",汪汪汪......"); 
}

wcDog.work();

4、使用原型对象的方式 prototype 关键字 代码如下:

function Dog(){ } 
Dog.prototype.name ="旺财"; 
Dog.prototype.eat = function(){ 
    alert(this.name + "是个吃货"); 
}

var wangcai = new Dog(); 
wangcai.eat();

5、混合模式(原型和构造函数) 代码如下:

function Car(name,price){
       this.name=name;
       this.price=price;
} 

Car.prototype.sell=function(){ 
    alert("我是"+this.name+",我现在卖"+this.price+"万元"); 
}

var camry = new Car("凯美瑞",27); 
camry.sell();

6、动态原型的方式(可以看作是混合模式的一种特例) 代码如下:

function Car(name,price){ 
    this.name=name; 
    this.price=price; 
    
    if(typeof Car.sell=="undefined"){ 
        Car.prototype.sell=function(){ 
    alert("我是"+this.name+",我现在卖"+this.price+"万元"); 
    } 
    
    Car.sell=true; 
} }

var camry = new Car("凯美瑞",27); 
camry.sell(); 

2、请指出 JavaScript 宿主对象和原生对象的区别?(必会)

原生对象

  • 独立于宿主环境的 ECMAScript 实现提供的对象”

  • 包含:Object、Function、Array、String、Boolean、Number、 Date 、 RegExp 、 Error 、 EvalError、RangeError、ReferenceError、SyntaxError、TypeError、 URIError

内置对象

  • 开发者不必明确实例化内置对象,它已被内部实例化了
  • 同样是“独立于宿主环境”。而 ECMA-262 只定义了两个内置对象,即 Global 和 Math

宿主对象

        BOM 和 DOM 都是宿主对象。因为其对于不同的“宿主”环境所展示的内容不同。其实说白了就是,ECMAScript 官方未定义的对象都属于宿主对象,因为其未定义的对象大多数是自己通过 ECMAScript 程序创建的对象

3、JavaScript 内置的常用对象有哪些?并列举该对象常用的方法? (必会)

对象及方法

  • Arguments 函数参数集合

  • Arguments[ ] 函数参数的数组

  • Arguments 一个函数的参数和其他属性
  • Arguments.callee 当前正在运行的函数
  • Arguments.length 传递给函数的参数的个数

Array 数组

  • length 属性 动态获取数组长度

  • delete 运算符 只能删除数组元素的值,而所占空间还在,总长度没变(arr.length)。
    • shift() 删除数组中第一个元素,返回删除的那个值,并将长度减 1。
    • pop() 删除数组中最后一个元素,返回删除的那个值,并将长度减 1。
    • slice(k,i) 从数组的第k个元素开始删除,删除i个元素, 并返回删除的几个值,长度减i
  • 数组增加运算符
    • unshift() 往数组前面添加一个或多个数组元素,长度要改变。arrObj.unshift(“a” , “b,“c”)
    • push() 往数组结尾添加一个或多个数组元素,长度要改变。arrObj.push(“a” ,“b”, “c”)
  • concat( ) 连接数组
  • join() 将一个数组转成字符串。返回一个字符串。
    • toLocaleString( ) 把数组转换成局部字符串
    • toString( ) 将数组转换成一个字符串
  • reverse() 将数组中各元素颠倒顺序
  • sort( ) 对数组元素进行排序
    var arr = [1, 5, 2, 7, 3, 4]; 
    var arr2 = arr.sort(function(a, b) { 
        // 从小到大 
        return a-b; 
        // 从大到小 
        return b-a; 
    })
    
    console.log(arr2); // 1,2,3,4,5,7 

  • slice( ) 返回数组的一部分
  • forEach 遍历所有元素
    var arr = [1, 2, 3]; 
    arr.forEach(function(item, index) { // 遍历数组的所有元素 
        console.log(index, item); 
    }); 

  • every 判断所有元素是否都符合条件 

        var arr = [1, 2, 3]; 
        var arr1 = arr.every(function(item, index) { 
            if (item < 4) { 
                return true; 
            } 
        })
    
    console.log(arr1); // true 

  • sort 排序
  • map 对元素重新组装,生成新数组
    ​var arr = [1, 5, 2, 7, 3, 4]; 
    var arr2 = arr.map(function(item, index) {
        return '<b>' + item + '</br>'; 
    })
    
    console.log(arr2); 
    
    ​
  • filter 过滤符合条件的元素
    var arr = [1, 2, 3, 4]; 
    var arr2 = arr.filter(function(item, index) {
        if (item>2) {
            return true; 
        }
    })
    
    console.log(arr2); // [3,4]

 String 字符串对象

  •  Length 获取字符串的长度。
    var len = strObj.length
  • toLowerCase() 将字符串中的字母转成全小写。如:
    strObj.toLowerCase()

  • toUpperCase() 将字符串中的字母转成全大写。如:
    strObj.toUpperCase()

  • charAt(index) 返回指定下标位置的一个字符。如果没有找到,则返回空字符串

  • substr() 在原始字符串,返回一个子字符串
  • substring() 在原始字符串,返回一个子字符串
    //区别:
    “abcdefgh”.substring(2,3) = “c”
    “abcdefgh”.substr(2,3) = “cde” 

  • split() 将一个字符串转成数组
  • charCodeAt( ) 返回字符串中的第 n 个字符的代码
  • concat( ) 连接字符串
  • fromCharCode( ) 从字符编码创建—个字符串
  • indexOf( ) 返回一个子字符串在原始字符串中的索引值(查找顺序从左往右查找)。如果没有找到,则返回-1
  • lastIndexOf( ) 从后向前检索一个字符串
  • localeCompare( ) 用本地特定的顺序来比较两个字符串
  • match( ) 找到一个或多个正则表达式的匹配
  • replace( ) 替换一个与正则表达式匹配的子串
  • search( ) 检索与正则表达式相匹配的子串
  • slice( ) 抽取一个子串
  • valueOf( )

Boolean 布尔对象

  • Boolean.toString( ) 将布尔值转换成字符串
  • Boolean.valueOf( ) Boolean 对象的布尔值

Date 日期时间

创建 Date 对象的方法

(1)创建当前(现在)日期对象的实例,不带任何参数

var today = new Date();

(2)创建指定时间戳的日期对象实例,参数是时间戳。

        时间戳:是指某一个时间距离 1970 年 1 月 1 日 0 时 0 分 0 秒,过去了多少毫秒值(1 秒 =1000 毫秒)

var timer = new Date(10000); //时间是 1970 年 1 月 1 日 0 时 0 分 10 秒 

(3)指定一个字符串的日期时间信息,参数是一个日期时间字符串

var timer = new Date(“2015/5/25 10:00:00”); 

(4)指定多个数值参数

var timer = new Date(2015+100,4,25,10,20,0); //顺序为:年、月、日、 时、分、秒,
//年、月、日是必须的

方法:

  • Date.getDate( ) 返回一个月中的某一天
  • Date.getDay( ) 返回一周中的某一天
  • Date.getFullYear( ) 返回 Date 对象的年份字段
  • Date.getHours( ) 返回 Date 对象的小时字段
  • Date.getMilliseconds( ) 返回 Date 对象的毫秒字段
  • Date.getMinutes( ) 返回 Date 对象的分钟字段
  • Date.getMonth( ) 返回 Date 对象的月份字段
  • Date.getSeconds( ) 返回 Date 对象的秒字段
  • Date.getTime( ) 返回 Date 对象的毫秒表示

Error 异常对象

  • Error.message 可以读取的错误消息
  • Error.name 错误的类型
  • Error.toString( ) 把 Error 对象转换成字符串
  • EvalError 在不正确使用 eval()时抛出
  • SyntaxError 抛出该错误用来通知语法错误
  • RangeError 在数字超出合法范围时抛出
  • ReferenceError 在读取不存在的变量时抛出
  • TypeError 当一个值的类型错误时,抛出该异常
  • URIError 由 URl 的编码和解码方法抛出

Function 函数构造器

  • Function.apply( ) 将函数作为一个对象的方法调用

  • Function.arguments[] 传递给函数的参数
  • Function.call( ) 将函数作为对象的方法调用
  • Function.caller 调用当前函数的函数
  • Function.length 已声明的参数的个数
  • Function.prototype 对象类的原型
  • Function.toString( ) 把函数转换成字符串

Math 数学对象

Math 对象是一个静态对象

  • Math.PI 圆周率
  • Math.abs() 绝对值
  • Math.ceil() 向上取整(整数加 1,小数去掉)
  • Math.floor() 向下取整(直接去掉小数)
  • Math.round() 四舍五入
  • Math.pow(x,y) 求 x 的 y 次方
  • Math.sqrt() 求平方根
  • Math.random()  求(1-10] 随机数 ?

Number 数值对象

  • Number.MAX_VALUE 最大数值
  • Number.MIN_VALUE 最小数值
  • Number.NaN 特殊的非数字值
  • Number.NEGATIVE_INFINITY 负无穷大
  • Number.POSITIVE_INFINITY 正无穷大
  • Number.toExponential( ) 用指数计数法格式化数字
  • Number.toFixed( ) 采用定点计数法格式化数字
  • Number.toLocaleString( ) 把数字转换成本地格式的字符串
  • Number.toPrecision( ) 格式化数字的有效位
  • Number.toString( ) 将—个数字转换成字符串
  • Number.valueOf( ) 返回原始数值

Object 基础对象

Object 含有所有 JavaScript 对象的特性的超类

  • Object.constructor 对象的构造函数
  • Object.hasOwnProperty( ) 检查属性是否被继承
  • Object.isPrototypeOf( ) 一个对象是否是另一个对象的原型
  • Object.propertyIsEnumerable( ) 是否可以通过 for/in 循环看到属性
  • Object.toLocaleString( ) 返回对象的本地字符串表示
  • Object.toString( ) 定义一个对象的字符串表示
  • Object.valueOf( ) 指定对象的原始值

RegExp 正则表达式对象

  • RegExp.exec( ) 通用的匹配模式
  • RegExp.global 正则表达式是否全局匹配
  • RegExp.ignoreCase 正则表达式是否区分大小写
  • RegExp.lastIndex 下次匹配的起始位置
  • RegExp.source 正则表达式的文本
  • RegExp.test( ) 检测一个字符串是否匹配某个模式
  • RegExp.toString( ) 把正则表达式转换成字符串

3、如何区分数组和对象?(必会)

方法一:通过 ES6 中的 Array.isArray 来识别

Array.isArray([]) //true 
Array.isArray({}) //false

方法二:通过 instanceof 来识别

[] instanceof Array //true 
{} instanceof Array //false

方法三:通过调用 constructor 来识别

{}.constructor //返回 object 
[].constructor //返回 Array

方法四:通过 Object.prototype.toString.call 方法来识别

Object.prototype.toString.call([]) //["object Array"] 
Object.prototype.toString.call({}) //["object Object"]

4、怎么判断两个对象相等?(必会)

- ES6 中有一个方法判断两个对象是否相等,这个方法判断是两个对象引用地址是否一致

let obj1= { 
    a: 1
}
let obj2 = {
    a: 1
} 

console.log(Object.is(obj1, obj2)) // false(内容一致但地址不一致)

let obj3 = obj1
console.log(Object.is(obj1, obj3)) // true(地址一致))
console.log(Object.is(obj2, obj3)) // false

- 当需求是比较两个对象内容是否一致时就没用了

想要比较两个对象内容是否一致,思路是要遍历对象的所有键名和键值是否都一致:

  1. 判断两个对象是否指向同一内存
  2. 使用 Object.getOwnPropertyNames 获取对象所有键名数组
  3. 判断两个对象的键名数组是否相等
  4. 遍历键名,判断键值是否都相等
let obj1 = { 
    a: 1, 
    b: {
      c: 2
    }
}

let obj2 = {
    b: {
      c: 3
    },
    a: 1
}

function isObjectValueEqual(a, b) {
    // 判断两个对象是否指向同一内存,指向同一内存返回 true
    if (a === b) {
        return true
    }
    
    // 获取两个对象键值数组
    let aProps = Object.getOwnPropertyNames(a)
    let bProps = Object.getOwnPropertyNames(b)
    // 判断两个对象键值数组长度是否一致,不一致返回 false
    if (aProps.length !== bProps.length) {
        return false
    }

    // 遍历对象的键值
    for (let prop in a) {

        // 判断 a 的键值,在 b 中是否存在,不存在,返回 false
        if (b.hasOwnProperty(prop)) {

            // 判断 a 的键值是否为对象,是则递归,不是对象直接判断键值是否相等,不相等返回 false
            if (typeof a[prop] === 'object') {
                if (!isObjectValueEqual(a[prop], b[prop])) return false
            } 
            else if (a[prop] !== b[prop]) {
                return false
            }
        } 
        else {
            return false
        }
    }

    return true
}

console.log(isObjectValueEqual(obj1, obj2)) // false

5、JavaScript 中怎么获取当前日期的月份?(必会)

方法

JavaScript 中获得当前日期是使用 new Date 这个内置对象的实例,其他一些进阶的操作也是基于这个内置对象的实例。

  • 获取完整的日期(默认格式): var date = new Date(); // Sat Jul 06 2019 19:59:27 GMT+0800 (中国标准时间)
  • 获取当前年份: var year = date.getFullYear(); // 2019
  • 获取当前月份: var month = date.getMonth() + 1; // 7
  • 获取当前日: var day = date.getDay(); // 6
  • 获取当前日期(年-月-日):
    month = (month > 9) ? month : ("0" + month); 
    day = (day < 10) ? ("0" + day) : day; 
    var today = year + "-" + month + "-" + day; // 2019-07-06

另外的一些操作:

  • date.getYear(); // 获取当前年份(2 位)
  • date.getFullYear(); // 获取完整的年份(4 位, 1970-????)
  • date.getMonth(); // 获取当前月份(0-11,0 代表 1 月)
  • date.getDate(); // 获取当前日(1-31)
  • date.getDay(); // 获取当前星期 X(0-6,0 代表星期天)
  • date.getTime(); // 获取当前时间(从 1970.1.1 开始的毫秒数)
  • date.getHours(); // 获取当前小时数(0-23)
  • date.getMinutes(); // 获取当前分钟数(0-59)
  • date.getSeconds(); // 获取当前秒数(0-59)
  • date.getMilliseconds(); // 获取当前毫秒数(0-999)
  • date.toLocaleDateString(); // 获取当前日期
  • date.toLocaleTimeString(); // 获取当前时间
  • date.toLocaleString( ); // 获取日期与时间

6、如何遍历对象的属性?(必会)

7、如何使用原生 JavaScript 给一个按钮绑定两个 onclick 事件?(必会)

8、JavaScript 中的作用域、预解析与变量声明提升? (必会)

9、变量提升与函数提升的区别?(必会)

10、什么是作用域链?如何延长作用域链?(必会)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值