文章目录
- 1、`JavaScript` 的基本类型有哪些?引用类型有哪些?`null` 和`undefined` 的区别?(必会)
- 2、如何判断 `JavaScript` 的数据类型?(必会)
- 3、创建对象有几种方法(必会)
- 4、简述创建函数的几种方式? (必会)
- 5、`Javascript` 创建对象的几种方式? (必会)
- 6、请指出 `JavaScript` 宿主对象和原生对象的区别?(必会)
- 7、`JavaScript` 内置的常用对象有哪些?并列举该对象常用的方法?(必会)
- 8、`===` 和 `==`的区别?(必会)
- 9、`null`,`undefined` 的区别(必会)
- 10、`JavaScript` 中什么情况下会返回 `undefined` 值?(必会)
1、JavaScript
的基本类型有哪些?引用类型有哪些?null
和undefined
的区别?(必会)
数据类型
基本数据类型:number
、string
、boolean
、null
、undefined
引用数据类型:function
、object
、Array
区别
undefined
:表示变量声明但未初始化时的值
null
:表示准备用来保存对象,还没有真正保存对象的值。从逻辑角度看,null
值表示一个空对象指针
JavaScript
(ECMAScript
标准)里共有 5 种基本类型:Undefined
, Null
, Boolean
, Number
,String
,和一种复杂类型 Object
。可以看到 null
和 undefined
分属不同的类型,未初始化定义的值用 typeof
检测出来是"undefined
"(字符串),而 null
值用 typeof
检测出来是"object"
(字符串)。任何时候都不建议显式的设置一个变量为 undefined
,但是如果保存对象的变量还没有真正保存对象,应该设置成 null
。实际上,undefined
值是派生自 null
值的,ECMAScript
标准规定对二者进行相等性测试要返回 true
2、如何判断 JavaScript
的数据类型?(必会)
JavaScript
数据类型一共有 7 种:Undefined
、Null
、Boolean
、String
、Symbol
、Number
、Object
除了 Object
之外的 6 种属于原始数据类型。有时,我们还会细分 Object
的类型,比如Array
, Function
,Date
,RegExp
等
判断方法1-- typeof
typeof
可以用来区分除了 Null
类型以外的原始数据类型,对象类型的可以从普通对象里面识别出函数:
typeof undefined // "undefined"
typeof null // "object"
typeof 1 // "number"
typeof "1" // "string"
typeof Symbol() // "symbol"
typeof function() {} // "function"
typeof {} // "object"
问题一:typeof
不能识别 null
,如何识别 null
?
答案:如果想要判断是否为 null
,可以直接使用===全等运算符来判断(或者使用下面的Object.prototype.toString
方法):
let a = null
a === null // true
问题二:typeof
作用于未定义的变量,会报错吗?
答案:不会报错,返回"undefined"
。
typeof randomVariable // "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)
的返回值是什么?
答案:"object"
。
typeof new Number(1) // "object"
typeof new String(1) // "object"
判断方法2-- 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
方法来覆盖默认行为。
判断方法3-- 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) // "Symbol"
由上面的示例可知,该方法没有办法区分数字类型和数字对象类型,同理还有字符串类型和字符串对象类型、布尔类型和布尔对象类型
另外,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
属性来覆盖默认行为,所以使用这个方法来判断数据类型也不一定是可靠的
判断方法4-- Array.isArray
Array.isArray(value)
可以用来判断 value
是否是数组:
Array.isArray([]) // true
Array.isArray({}) // false
(function () {console.log(Array.isArray(arguments))}()) // false
3、创建对象有几种方法(必会)
创建方法
1、字面量对象 // 默认这个对象的原型链指向 object
var o1 = {name: '01'};
2、通过 new Object
声明一个对象
var o11 = new Object({name: '011'});
3、使用显式的构造函数创建对象
var M = function(){this.name='o2'};
var o2 = new M();
o2.__proto__=== M.prototype
o2 的构造函数是 M
o2 这个普通函数,是 M 这个构造函数的实例
4、object.create()
var P = {name:'o3'};
var o3 = Object.create(P);
4、简述创建函数的几种方式? (必会)
第一种(函数声明):
function sum1(num1,num2){
return num1+num2;
}
第二种(函数表达式)
var sum2 = function(num1,num2){
return num1+num2;
}
第三种(函数对象方式)
var sum3 = new Function("num1","num2","return num1+num2");
5、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();
以上几种,是 javascript
中最常用的创建对象的方式
6、请指出 JavaScript
宿主对象和原生对象的区别?(必会)
原生对象
ECMA-262
把本地对象(native object
)定义为“独立于宿主环境的 ECMAScript
实现提供的对象
“本地对象”包含哪些内容:Object
、Function
、Array
、String
、Boolean
、Number
、Date
、RegExp
、Error
、EvalError
、RangeError
、ReferenceError
、SyntaxError
、TypeError
、URIError
由此可以看出,本地对象就是 ECMA-262
定义的类(引用类型)
内置对象
ECMA-262
把内置对象(built-in object
)定义为“由 ECMAScript
实现提供的、独立 于宿主环境的所有对象,在 ECMAScript
程序开始执行时出现”。这意味着开发者不必明 确实例化内置对象,它已被实例化了同样是“独立于宿主环境”。根据定义我们似乎很难分清“内置对象”与“本地对象”的区别。而 ECMA-262
只定义了两个内置对象,即 Global
和 Math
(它们也是本地对象,根据定义,每个内置对象都是本地对象)。如此就可以理解了。内置对象是本地对象的一种
宿主对象
何为“宿主对象”?主要在这个“宿主”的概念上,ECMAScript
中的“宿主”当然就是我们网页的运行环境,即“操作系统”和“浏览器”
所有非本地对象都是宿主对象(host object
),即由 ECMAScript
实现的宿主环境提供的对象。所有的 BOM
和 DOM
都是宿主对象。因为其对于不同的“宿主”环境所展示的内容不同。其实说白了就是,ECMAScript
官方未定义的对象都属于宿主对象,因为其未定义的对象大多数是自己通过 ECMAScript
程序创建的对象
7、JavaScript
内置的常用对象有哪些?并列举该对象常用的方法?(必会)
对象及方法
Arguments
函数参数集合
Arguments[ ]
函数参数的数组Arguments
一个函数的参数和其他属性Arguments.callee
当前正在运行的函数Arguments.length
传递给函数的参数的个数
Array
数组
length
属性 动态获取数组长度join()
将一个数组转成字符串。返回一个字符串reverse()
将数组中各元素颠倒顺序delete
运算符 只能删除数组元素的值,而所占空间还在,总长度没变(arr.length
)shift()
删除数组中第一个元素,返回删除的那个值,并将长度减 1pop()
删除数组中最后一个元素,返回删除的那个值,并将长度减 1unshift()
往数组前面添加一个或多个数组元素,长度要改变。arrObj.unshift(“a” ,“b,“c”)
push()
往数组结尾添加一个或多个数组元素,长度要改变。arrObj.push(“a” ,“b”,“c”)
concat( )
连接数组slice( )
返回数组的一部分sort( )
对数组元素进行排序splice( )
插入、删除或替换数组的元素toLocaleString( )
把数组转换成局部字符串toString( )
将数组转换成一个字符串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
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]
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 对象的毫秒表示Date.getTimezoneOffset( )
判断与 GMT 的时间差Date.getUTCDate( )
返回该天是一个月的哪一天(世界时)Date.getUTCDay( )
返回该天是星期几(世界时)Date.getUTCFullYear( )
返回年份(世界时)Date.getUTCHours( )
返回 Date 对象的小时字段(世界时)Date.getUTCMilliseconds( )
返回 Date 对象的毫秒字段(世界时)Date.getUTCMinutes( )
返回 Date 对象的分钟字段(世界时)Date.getUTCMonth( )
返回 Date 对象的月份(世界时)Date.getUTCSeconds( )
返回 Date 对象的秒字段(世界时)Date.getYear( )
返回 Date 对象的年份字段(世界时)Date.parse( )
解析日期/时间字符串Date.setDate( )
设置一个月的某一天Date.setFullYear( )
设置年份,也可以设置月份和天Date.setHours( )
设置 Date 对象的小时字段、分钟字段、秒字段和毫秒字段Date.setMilliseconds( )
设置 Date 对象的毫秒字段Date.setMinutes( )
设置 Date 对象的分钟字段和秒字段Date.setMonth( )
设置 Date 对象的月份字段和天字段Date.setSeconds( )
设置 Date 对象的秒字段和毫秒字段Date.setTime( )
以毫秒设置 Date 对象Date.setUTCDate( )
设置一个月中的某一天(世界时)Date.setUTCFullYear( )
设置年份、月份和天(世界时)Date.setUTCHours( )
设置 Date 对象的小时字段、分钟字段、秒字段和毫秒字段(世界时)Date.setUTCMilliseconds( )
设置 Date 对象的毫秒字段(世界时)Date.setUTCMinutes( )
设置 Date 对象的分钟字段和秒字段(世界时)Date.setUTCMonth( )
设置 Date 对象的月份字段和天数字段(世界时)Date.setUTCSeconds( )
设置 Date 对象的秒字段和毫秒字段(世界时)Date.setYear( )
设置 Date 对象的年份字段Date.toDateString( )
返回 Date 对象日期部分作为字符串Date.toGMTString( )
将 Date 转换为世界时字符串Date.toLocaleDateString( )
回 Date 对象的日期部分作为本地已格式化的字符串Date.toLocaleString( )
将 Date 转换为本地已格式化的字符串Date.toLocaleTimeString( )
返回 Date 对象的时间部分作为本地已格式化的字符串Date.toString( )
将 Date 转换为字符串Date.toTimeString( )
返回 Date 对象日期部分作为字符串Date.toUTCString( )
将 Date 转换为字符串(世界时)Date.UTC( )
将 Date 规范转换成毫秒数Date.valueOf( )
将 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()
求平方根
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( )
把正则表达式转换成字符串
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( )
抽取一个子串
toLocaleLowerCase( )
把字符串转换小写
toLocaleUpperCase( )
将字符串转换成大写
toLowerCase( )
将字符串转换成小写
toString( )
返回字符串
toUpperCase( )
将字符串转换成大写
valueOf( )
8、===
和 ==
的区别?(必会)
区别:
===
:三个等号我们称为等同符,当等号两边的值为相同类型的时候,直接比较等号两边的值,值相同则返回 true
,若等号两边的值类型不同时直接返回 false
。也就是说三个等号既要判断值也要判断类型是否相等
==
:两个等号我们称为等值符,当等号两边的值为相同类型时比较值是否相同,类型不同时会发生类型的自动转换,转换为相同的类型后再作比较。也就是说两个等号只要值相等就可以
9、null
,undefined
的区别(必会)
区别
null
表示一个对象被定义了,值为“空值”;
undefined
表示不存在这个值
typeof undefined //"undefined"
undefined
:是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但还没有定义。当尝试读取时会返回 undefined
;例如变量被声明了,但没有赋值时,就等于 undefined
typeof null //"object"
null
: 是一个对象(空对象, 没有任何属性和方法);例如作为函数的参数,表示该函数的参数不是对象;
注意:
在验证 null
时,一定要使用 ===
,因为 ==
无法分别 null
和 undefined
undefined
表示"缺少值",就是此处应该有一个值,但是还没有定义。
典型用法是:
- 1、变量被声明了,但没有赋值时,就等于
undefined
- 2、调用函数时,应该提供的参数没有提供,该参数等于
undefined
- 3、对象没有赋值的属性,该属性的值为
undefined
- 4、函数没有返回值时,默认返回
undefined
null
表示"没有对象",即该处不应该有值。
典型用法是:
- 作为函数的参数,表示该函数的参数不是对象
- 作为对象原型链的终点
10、JavaScript
中什么情况下会返回 undefined
值?(必会)
1、访问声明,但是没有初始化的变量
var aaa;
console.log(aaa); // undefined
2、访问不存在的属性
var aaa = {};
console.log(aaa.c);
3、访问函数的参数没有被显式的传递值
(function (b){
console.log(b); // undefined
})();
4、访问任何被设置为 undefined 值的变量
var aaa = undefined;console.log(aaa); // undefined
5、没有定义 return 的函数隐式返回
function aaa(){}console.log(aaa()); // undefined
6、函数 return 没有显式的返回任何内容
function aaa(){
return;
}
console.log(aaa()); // undefined