1. JavaScript 的基本类型有哪些?引用类型有哪些?null 和 undefined 的区别?
数据类型:
基本数据类型:Number、String、Boolean、undefined 、null
引用数据类型:Function、Object、Array
区别:
undefined:表示变量声明但未初始化
时的值
null:表示准备用来保存对象,还没有真正保存对象
的值。从逻辑角度看,null 值表示一个空对象指针
ECMA 标准要求 null 和 undefined 等值判断返回 true
null == undefined // true
null === undefined // false
2. 如何判断 JavaScript 的数据类型?
typeof
typeof
可以用来区分除了 null 类型以外的原始数据类型
,对象类型的可以从普通对象里面识别出函数:
typeof undefined // "undefined"
typeof null // "object"
typeof 1 // "number"
typeof "1" // "string"
typeof Symbol() // "symbol"
typeof function() {} // "function"
typeof {} // "object"
// ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
问题一: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"
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(3).slice(8, -1) // "Number"
Object.prototype.toString.call(new Number(3)).slice(8, -1) // "Number"
Object.prototype.toString.call('3').slice(8, -1) // "String"
Object.prototype.toString.call(new String(3)).slice(8, -1) // "String"
Object.prototype.toString.call(true).slice(8, -1) // "Boolean"
Object.prototype.toString.call(new Boolean(true)).slice(8, -1) // "Boolean"
Object.prototype.toString.call(undefined).slice(8, -1) // "Undefined"
Object.prototype.toString.call(null).slice(8, -1) // "Null"
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 属性来覆盖默认行 为,所以使用这个方法来判断数据类型也不一定是可靠的
Array.isArray
Array.isArray(value)可以用来判断 value 是否是数组:
Array.isArray([]) // true
Array.isArray({}) // false
(function () {console.log(Array.isArray(arguments))}()) // false
3. 简述创建函数的几种方式?
第一种(函数声明)
function sum1(num1, num2) {
return num1 + num2;
}
第二种(函数表达式)
var sum2 = function (num1, num2) {
return num1 + num2;
}
第三种(函数对象方式)
var sum3 = new Function("num1", "num2", "return num1+num2")
4. 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 中最常用的创建对象的方式
5. 请指出 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 程序创建的对象