1. document load 和 document ready 的区别
页面加载完成有两种事件
load是当页面所有资源全部加载完成后(包括DOM文档树,css文件,js文件,图片资源等),执行一个函数
问题:如果图片资源较多,加载时间较长,onload后等待执行的函数需要等待较长时间,所以一些效果可能受到影响$(document).ready()是当DOM文档树加载完成后执行一个函数 (不包含图片,css等)所以会比load较快执行
在原生的jS中不包括ready()这个方法,只有load方法就是onload事件
2. JavaScript 中如何检测一个变量是一个 String 类型?
三种方法(typeof、constructor、Object.prototype.toString.call())
1). typeof
2). constructor
3). Object.prototype.toString.call()
3. 请用 js 去除字符串空格?
replace 正则匹配方法、str.trim()方法、JQ 方法:$.trim(str)方法
1). replace 正则匹配方法
去除字符串内所有的空格:str = str.replace(/\s*/g,"");
去除字符串内两头的空格:str = str.replace(/^\s|\s$/g,"");
去除字符串内左侧的空格:str = str.replace(/^\s*/,"");
去除字符串内右侧的空格:str = str.replace(/(\s*$)/g,"");
2). str.trim()方法
trim()方法
是用来删除字符串两端
的空白字符并返回,trim 方法并不影响
原来的字符串本身,它返回的是一个新的字符串。
缺陷:只能去除字符串两端的空格,不能去除中间的空格
3). jquery方法:$.trim(str)
方法
$.trim()
函数用于去除字符串两端
的空白字符。
注意
:$.trim()函数会移除
字符串开始和末尾处的所有
换行符,空格(包括连续的空格)和制表符。如果这些空白字符在字符串中间
时,它们将被保留
,不会被移除。
4. js 是一门怎样的语言,它有什么特点
1).脚本语言
JavaScript
是一种解释型
的脚本语言,C、C++等语言先编译后执行,而 JavaScript 是在程序的运行过程中
逐行进行解释
。
2).基于对象
JavaScript
是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。
3).简单
JavaScript
语言中采用的是弱类型
的变量类型,对使用的数据类型未做出严格的要求,是基于 Java 基本语句和控制的脚本语言
,其设计简单紧凑
。
4).动态性。
JavaScript
是一种采用事件驱动
的脚本语言,它不需要经过 Web 服务器就可以对用户的输入做出响应。
5).跨平台性
JavaScript
脚本语言不依赖于操作系统,仅需要浏览器
的支持。
5.== 和 === 的不同
==
是抽象相等
运算符,而===
是严格相等
运算符。
==运算符是在进行必要的类型转换后,再比较。
===运算符不会进行类型转换,所以如果两个值不是相同的类型,会直接返回false。
如果你对==和===的概念不是特别了解,建议大多数情况下使用===
6.怎样添加、移除、移动、复制、创建和查找节点?
1)创建新节点
createDocumentFragment() //创建一个 DOM 片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
2)添加、移除、替换、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入
3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的 Name 属性的值
getElementById() //通过元素 Id,唯一性
7.事件委托是什么
利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行
1). 那什么样的事件可以用事件委托,什么样的事件不可以用呢?
适合用事件委托的事件:
click
,mousedown
,mouseup
,keydown
,keyup
,keypress
。
值得注意的是,
mouseover
和mouseout
虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。
2). 为什么要用事件委托
-
提高性能
- 新添加的元素还会有之前的事件。
3). 事件冒泡与事件委托的对比
事件冒泡
:box 内部无论是什么元素,点击后都会触发 box 的点击事件
事件委托
:可以对 box 内部的元素进行筛选
4). 事件委托怎么取索引?
8.require 与 import 的区别
1). 两者的加载方式不同
require
是在运行时
加载,而import
是在编译时
加载
require('./a')(); // a 模块是一个函数,立即执行 a 模块函数
var data = require('./a').data; // a 模块导出的是一个对象
var a = require('./a')[0]; // a 模块导出的是一个数组 =>用在哪都行
import $ from 'jquery';
import * as _ from '_';
import {a,b,c} from './a';
import {default as alias, a as a_a, b, c} from './a'; =>用在开头
2). 规范不同
require
是 CommonJS/AMD
规范,import
是 ESMAScript6+
规范
3).
require 特点:
社区方案
,提供了服务器/浏览器
的模块加载方案,非语言层面的标准,只能在运行时确定模块的依赖关系
及输入/输出
的变量,无法进行静态优化
。
import 特点:
语言规格
层面支持模块功能,支持编译时静态分析
,便于 JS 引入宏和类型检验,动态绑定
。
9.javascript 对象的几种创建方式
1). Object 构造函数创建
var Person = new Object();
Person.name = "Nike";
Person.age = 29;
这行代码创建了 Object 引用类型的一个新实例,然后把实例保存在变量 Person 中。
2). 使用对象字面量表示法
对象
字面量
是对象定义
的一种简写形式,目的在于简化创建
包含大量属性的对象的过程。也就是说,第一种和第二种方式创建对象的方法其实都是一样的,只是写法上的区别。
缺点:它们都是用了同一个接口创建
很多对象
,会产生大量的重复代码,就是如果你有 100 个对象,那你要输入 100 次很多相同的代码。那我们有什么方法来避免过多的重复代码呢,就是把创建对象的过程封装
在函数体内,通过函数的调用直接生成对象。
3). 使用工厂模式创建对象
在使用工厂模式创建对象的时候,我们都可以注意到,在 createPerson 函数中,返回的是一个对象。那么我们就无法判断返回的对象究竟是一个什么样的类型。于是就出现了第四种创建对象的模式。
4). 使用构造函数创建对象
对比工厂模式,我们可以发现以下区别:
1.没有显示地创建对象
2.直接将属性和方法赋给了 this 对象
3.没有 return 语句
4.终于可以识别的对象的类型。
缺点:每个方法都要在每个实例上
重新创建
一遍,方法指的就是我们在对象里面定义的函数。如果方法的数量很多,就会占用很多不必要
的内存。
5). 原型创建对象模式
使用原型创建对象的方式,可以让所有对象实例共享它所包含的属性和方法。
6). 组合使用构造函数模式和原型模式
10.JavaScript 继承的方式和优缺点
1). 原型链继承
缺点:
1.引用类型的属性被所有实例共享
2.在创建Child
的实例时,不能向Parent
传参
2). 借用构造函数(经典继承)
优点:
1.避免了引用类型的属性被所有实例共享
2.可以在Child
中向Parent
传参
缺点:
方法都在
构造函数
中定义,每次创建实例都会创建一遍方法。
3). 组合继承
优点:
融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。
4). 原型式继承
缺点:
包含
引用类型
的属性值始终都会共享
相应的值,这点跟原型链继承一样。
5). 寄生式继承
缺点:
跟借用
构造函数模式
一样,每次创建对象都会创建一遍方法。
6). 寄生组合式继承
优点:
1.这种方式的高效率体现它只调用了一次
Parent
构造函数,并且因此避免了在Parent.prototype
上面创建不必要的、多余的属性。
2.与此同时,原型链
还能保持不变;
3.因此,还能够正常使用instanceof
和isPrototypeOf
。
开发人员普遍认为
寄生组合式
继承是引用类型最理想
的继承范式
11.什么是原型链?
通过一个对象的proto
可以找到它的原型对象
,原型对象
也是一个对象,就可以通过原型对象的proto
,最后找到了我们的Object.prototype
,从实例的原型对象开始一直到Object.prototype
就是我们的原型链
12.复杂数据类型如何转变为字符串
- 首先,会调用
valueOf
方法,如果方法的返回值是一个基本数据类型
,就返回这个值, - 如果调用
valueOf
方法之后的返回值仍旧是一个复杂数据类型
,就会调用该对象的toString
方法, - 如果
toString
方法调用之后的返回值是一个基本数据类型
,就返回这个值, - 如果
toString
方法调用之后的返回值是一个复杂数据类型
,就报一个错误。
13.javascript 的 typeof 返回哪些数据类型
string
boolean
number
Object
Function
undefined
symbol(ES6)
14. 在 css/js 代码上线之后开发人员经常会优化性能,从用户刷新网页开始,一次 js 请求一般情况下有哪些地方会有缓存处理?
dns 缓存
cdn 缓存
浏览器缓存
服务器缓存
15.列举 3 种强制类型转换和 2 种隐式类型转换
强制
- parseInt
- parseFloat
- Number
隐式
- (+ -)
16.你对闭包的理解?优缺点?
概念:闭包就是能够读取其他函数内部变量的函数。三大特性:
- 函数嵌套函数。
- 函数内部可以引用外部的参数和变量。
- 参数和变量不会被垃圾回收机制回收。
优点:
- 希望一个变量长期存储在内存中。
- 避免全局变量的污染。
- 私有成员的存在。
缺点:
- 常驻内存,增加内存使用量。
- 使用不当会很容易造成内存泄露。
17.如何判断 NaN
isNaN()方法
18.new 一个对象的过程中发生了什么
1). 创建空对象;
var obj = {};
2). 设置新对象的constructor
属性为构造函数的名称,设置新对象的proto
属性指向构造函数的prototype
对象;
obj.__proto__ = ClassA.prototype;
3). 使用新对象调用函数,函数中的this
被指向新实例对象:
ClassA.call(obj);
//{}.构造函数();
4).
如果
无返回值
或者返回一个非对象值
,则将新对象
返回;
如果返回值是一个新对象
的话那么直接返回该对象
19.for in 和 for of
1). for in
1.一般用于
遍历对象
的可枚举
属性,以及对象从构造函数原型中继承的属性。对于每个不同的属性,语句都会被执行
2.不建议使用
for in
遍历数组,因为输出的顺序是不固定
的
3.如果迭代的对象的变量值是
null
或者undefined
,for in
不执行循环体,建议在使用for in
循环之前,先检查该对象的值是不是null
或者undefined
2). for of
for…of 语句在可迭代对象(包括
Array
,Map
,Set
,String
,TypedArray
,arguments
对象等等)上创建一个迭代循环
,调用自定义迭代钩子
,并为每个不同属性的值执行语句
20. 如何判断JS变量的一个类型
typeof
instanceof
constructor
prototype