JavaScript 具备七种内置数据类型,它们分别是:html
类型判断经常使用的方法面试
使用 typeof 判断类型
编程
typeof 5 // "number"
typeof 'lucas' // "string"
typeof undefined // "undefined"
typeof true // "boolean"
typeof null // "object"
const foo = () => 1
typeof foo // "function"
const foo = {}
typeof foo // "object"
const foo = []
typeof foo // "object"
const foo = new Date()
typeof foo // "object"
const foo = Symbol("foo")
typeof foo // "symbol"
复制代码
总结:使用 typeof 能够准确判断出除 null 之外的基本类型,以及 function 类型、symbol 类型;null 会被 typeof 判断为 object。浏览器
使用 instanceof 判断类型
使用 a instanceof B 判断的是:a 是否为 B 的实例,即 a 的原型链上是否存在 B 构造函数。所以若是使用:缓存
function Person(name) {
this.name = name
}
const p = new Person('lucas')
p instanceof Person
复制代码
这里 p 是 Person 构造出来的实例。同时,顺着 p 的原型链,也能找到 Object 构造函数:安全
p.__proto__.__proto__ === Object.prototype
p instanceof Object
复制代码
注意:服务器
5 instanceof Number // false
new Number(5) instanceof Number // true
复制代码
咱们使用如下代码来模拟 instanceof 原理:网络
// L 表示左表达式,R 表示右表达式
const instanceofMock = (L, R) => {
if (typeof L !== 'object') {
return false
}
while (true) {
if (L === null) {
// 已经遍历到了最顶端
return false
}
if (R.prototype === L.__proto__) {
return true
}
L = L.__proto__
}
}
复制代码
使用 constructor 和 Object.prototype.toString 判断类型
闭包
使用 Object.prototype.toString 判断类型,咱们称之为“万能方法”,“终极方法”:app
console.log(Object.prototype.toString.call(1))
// [object Number]
console.log(Object.prototype.toString.call('lucas'))
// [object String]
console.log(Object.prototype.toString.call(undefined))
// [object Undefined]
console.log(Object.prototype.toString.call(true))
// [object Boolean]
console.log(Object.prototype.toString.call({}))
// [object Object]
console.log(Object.prototype.toString.call([]))
// [object Array]
console.log(Object.prototype.toString.call(function(){}))
// [object Function]
console.log(Object.prototype.toString.call(null))
// [object Null]
console.log(Object.prototype.toString.call(Symbol('lucas')))
// [object Symbol]
复制代码
使用 constructor 能够查看目标的构造函数,这也能够进行类型判断,但也存在着问题,具体请看:
var foo = 5
foo.constructor
// ƒ Number() { [native code] }
var foo = 'Lucas'
foo.constructor
// ƒ String() { [native code] }
var foo = true
foo.constructor
// ƒ Boolean() { [native code] }
var foo = []
foo.constructor
// ƒ Array() { [native code] }
var foo = {}
foo.constructor
// ƒ Object() { [native code] }
var foo = () => 1
foo.constructor
// ƒ Function() { [native code] }
var foo = new Date()
foo.constructor
// ƒ Date() { [native code] }
var foo = Symbol("foo")
foo.constructor
// ƒ Symbol() { [native code] }
var foo = undefined
foo.constructor
// VM257:1 Uncaught TypeError: Cannot read property 'constructor' of undefined
at <anonymous>:1:5
var foo = null
foo.constructor
// VM334:1 Uncaught TypeError: Cannot read property 'constructor' of null
at <anonymous>:1:5
复制代码
咱们发现对于 undefined 和 null,若是尝试读取其 constructor 属性,将会进行报错。而且 constructor 返回的是构造函数自己,通常使用它来判断类型的状况并很少见。
浅克隆之因此被称为浅克隆,是由于对象只会被克隆最外部的一层,至于更深层的对象,则依然是经过引用指向同一块堆内存.
// 浅克隆函数
function shallowClone(o) {
const obj = {};
for ( let i in o) {
obj[i] = o[i];
}
return obj;
}
// 被克隆对象
const oldObj = {
a: 1,
b: [ 'e', 'f', 'g' ],
c: { h: { i: 2 } }
};
const newObj = shallowClone(oldObj);
console.log(newObj.c.h, oldObj.c.h); // { i: 2 } { i: 2 }
console.log(oldObj.c.h === newObj.c.h); // true
复制代码
涉及面试题:为何要使用模块化?都有哪几种方式能够实现模块化,各有什么特色?
使用模块化的好处:
模块化的方式
AMD/CMD的区别
不少人说requireJS是异步加载模块,SeaJS是同步加载模块,这么理解其实是不许确的,其实加载模块都是异步的,只不过AMD依赖前置,js能够方便知道依赖模块是谁,当即加载,而CMD就近依赖,须要使用把模块变为字符串解析一遍才知道依赖了那些模块,这也是不少人诟病CMD的一点,牺牲性能来带来开发的便利性,实际上解析模块用的时间短到能够忽略
为何咱们说两个的区别是依赖模块执行时机不一样,为何不少人认为ADM是异步的,CMD是同步的(除了名字的缘由。。。)
一样都是异步加载模块,AMD在加载模块完成后就会执行改模块,全部模块都加载执行完后会进入require的回调函数,执行主逻辑,这样的效果就是依赖模块的执行顺序和书写顺序不必定一致,看网络速度,哪一个先下载下来,哪一个先执行,可是主逻辑必定在全部依赖加载完成后才执行
CMD加载完某个依赖模块后并不执行,只是下载而已,在全部依赖模块加载完成后进入主逻辑,遇到require语句的时候才执行对应的模块,这样模块的执行顺序和书写顺序是彻底一致的
这也是不少人说AMD用户体验好,由于没有延迟,依赖模块提早执行了,CMD性能好,由于只有用户须要的时候才执行的缘由
一、AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块 二、CMD推崇就近依赖,只有在用到某个模块的时候再去require
参考:www.cnblogs.com/SanMaoSpace… JavaScript是一种基于对象(Object)和事件驱动(Event Driven)并具备相对安全性的客户端脚本语言。它最初由网景公司(Netscape)的Brendan Eich设计,是一种动态、弱类型、基于原型的语言,内置支持类。
特色
一种解释性执行的脚本语言。 JavaScript的语法基本结构形式与C、C++、Java十分相似。但在使用前,不像这些语言须要先编译,而是在程序运行过程当中被逐行地解释
一种基于对象的脚本语言。
一种简单弱类型脚本语言。
一种相对安全脚本语言。
一种事件驱动脚本语言。
一种跨平台性脚本语言。
优势
缺点
涉及面试题:什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题?