JavaScript3
1.移动端上什么是点击穿透?
点击穿透有3种:
点击穿透问题:
点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件跨页面点击穿透问题:如果按钮下面恰好是一个有. href属性的a标签,那么.页面就会发生跳转另一种跨页面点击穿透问题:这次没有mask 了,直接点击页内按钮跳转至新页,然后发现新页面中对应位置元素的click事件被触发了。
解决方案:
-
只有touch,把页面内所有click 全部换成 touch-事件( touchstart , ' touchend’ , ' tap')。
-
只用click,下下策,因为会带来 300ms延迟,页面内任何一个自定义交互都将增加300毫秒延迟。
-
tap后延迟350ms再隐藏 mask。改动最小,缺点是隐藏mask变慢了,350ms 还是能感觉到慢的。
-
pointer-events
2.JQ绑定事件的几种方式? on bind ?
-
jQuery中提供了四种事件监听方式,分别是bind , live,delegate、on,对应的解除监听的函数分别是unbind、die、undelegate、off。
-
Bind( )是使用频率较高的一种,作用就是在选择到的元素上绑定特定事件类型的监听函数;
-
Live()可以对后生成的元素也可以绑定相应的事件,处理机制就是把事件绑定在DOM树的根节点上,而不是直接绑定在某个元素上;
-
Delegate()采用了事件委托的概念,不是直接为子元素绑定事件,而是为其父元素(或祖先元素也可)绑定事件,当在div内任意元素上点击时,事件会一层层从event target向上冒泡,直至到达你为其绑定事件的元素;
-
on( )方法可以绑定动态添加到页面元素的事件,on()方法绑定事件可以提升效率;
3.Jq中如何将一个jq对象转化为dom对象?
-
方法一:jQuery对象是―个数据对象,可以通过[index]的方法,来得到相应的 DOM对象。
-
方法二:jQuery本身提供,通过.get(index)方法,得到相应的DOM对象。
4.Jq中有几种选择器?分别是什么?
-
基本选择器:它由元素ID、元素名、多个选择符组成,通过基本选择器可以实现大多数页面元素的查找。#id,class
-
层次选择器:通过DOM元素间的层次关系获取元素,其主要的层次关系包括后代、父子、相邻、兄弟关系,通过其中某类关系可以方便快捷地定位元素。parent>child
-
过滤选择器:添加过滤条件,比如“$(“div:first”)”返回div元素集合的第一个div元素,first是过滤条件。$(“div:first”)
-
内容过滤选择器:根据元素中的文字内容或所包含的子元素特征获取元素,其文字内容可以绝对模糊或绝对匹配进行元素定位。:parent
-
属性过滤器:根据元素的某个属性获取元素,如ID号或匹配属性值的内容,并以“[”号开始、一"]"号结束。
-
表单对象属性过滤选择器:通过表单中的某对象属性特征获取该元素,如enabled、disabled、checked、selected属性。
-
表单过滤器:表单选择器,该选择器专为表单量身打造,通过它可以在页面中快速定位某表单对象。
5.Jq中怎么样编写插件?
-
添加一个新的全局函数添加一个全局函数,我们只需如下定义:
jQuery.foo = function) {
alert(This is a test、This is only a test.');
};-
第二种是对象级别的插件开发
(function($){$.fn.extend({pulginName:function(opt,callback){
})(jQuery)6.map和each有什么区别?
-
map()方法主要用来遍历操作数组和对象,会返回一个新的数组。$.map()方法适用于将数组或对象每个项目新阵列映射到一个新数组的函数;
-
each()主要用于遍历jquery对象,返回的是原来的数组,并不会新创建一个数组。
7.Jq中的attr和prop有什么区别
-
对于HTML元素本身就带有的固有属性,在处理时,使用prop方法。
-
对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法。
8.简述下this和定义属性和方法的时候有什么区别?Prototype?
-
this表示当前对象,如果在全局作用范围内使用this,则指代当前页面对象window;如果在函数中使用this ,则this 指代什么是根据运行时此函数在什么对象上被调用。我们还可以使用apply和call两个全局方法来改变函数中this的具体指向。
-
prototype本质上还是―个JavaScript对象。并且每个函数都有一个默认的prototype 属性。
9.什么是预编译语音|预编译处理器?
-
Sass是一种CSS 预处理器语言,通过编程方式生成,CSS代码。因为可编程,所以操控灵活性自由度高,方便实现一些直接编写CSS代码较困难的代码。同时;因为Sass是生成CSS的语言,所以写出来的Sass文件是不能直接用的,必须经讨编译器编译成,CSS 文件才能使用。
-
CSS预处理器是―种语言用来为CSS增加一些编程的的特性,无需考虑浏览器的兼容性问题,例如你可以在CSS中使用变量、简单的程序逻辑、函数等等在编程语言中的一些基本技巧,可以让你的CSS更见简洁,适应性更强,代码更直观等诸多好处。最常用的css预处理器有sass、less css、stylus。
10.ajax和jsonp?
-
相同点:都是请求一个url。
-
不同点:ajax的核心是通过xmlHttpRequest:获取内容,jsonp的核心是动态添加。
11.简述下你理解的面向对象?
-
万物皆对象,把一个对象抽象成类,具体上就是把一个对象的静态特征和动态特征抽象成属性和方法,也就是把―类事物的算法和数据结构封装在一个类之中,程序就是多个对象和互相之间的通信组成的。
-
面向对象具有封装性,继承性,多态性。
-
封装:隐蔽了对象内部不需要暴露的细节,使得内部细节的变动跟外界脱离,只依靠接口进行通信.封装性降低了编程的复杂性、通过继承,使得新建一个类变得容易,一个类从派生类那里获得其非私有的方法和公用属性的繁琐工作交给了编译器、而继承和实现接口和运行时的类型绑定机制所产生的多态,使得不同的类所产生的对象能够对相同的消息作出不同的反应,极大地提高了代码的通用性。
12.你对数据校验是怎么样处理的? jquery.validate?
通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的一个校验值。接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,就说明数据是完整的。用正则表达式来处理;jquery.validate:为表单验证插件。
13.如何对登录的账号密码进行加密?
Md5
14.在jq中mouseover mouseenter mouseout mouseleave和hover有什么关联?
-
mouseenter 与mouseover:不论鼠标指针穿过被选中元素或其子元素,都会触发mouseover事件。只有在鼠标指针穿过被选元素时,才会触发mouseentr事件。
-
mouseout 与mouseleave:不论鼠标离开被选元素还是任何子元素,都会触发mouseout事件。只有在鼠标指针离开被选元素时,才会触发mouseleave事件。
-
hover:hover是个符合方法,相当于mouseenter+mouseleave。
15.jsonp原理?缺点?
-
工作原理: 使用script标签实现跨域访问,可在url中指定回调函数,获取JSON数据并在指定的回调函数中执行jquery 实现jsonp。缺点:只支持GET方式的jsonp 实现,是一种脚本注入行为存在一定的安全隐患。如果返回的数据格式有问题或者返回失败了,并不会报错。
-
16.split() join()?slice() splice()?
-
split()切割成数组形态。
-
join() 将数组转化为字符串。
-
slice() 方法可从已有的数组中返回选定的元素。
-
splice()方法向/从数组中添加/删除项目,然后返回被删除的项目。
17.disabled和readyonly区别?
-
readonly只针对input(text / password)和 textarea有效,而 disabled对于所有的表单元素都有效,当表单元素在使用了disabled后,当我们将表单以POST或GET的方式提交的话,这个元素的值不会被传递出去,而 readonly 会将该值传递出去。
18.JavaScript提供了哪几种“异步模式”?
-
回调函数( callbacks)。
-
事件监听。
-
Promise对象。
19.什么是移动端的300ms延迟?什么是点击穿透?解决方案?
-
移动端300ms延迟:假定这么一个场景。用户在·浏览器里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,浏览器就等待300毫秒,以判断用户是否再次点击了屏幕。也就是说,当我们点击页面的时候移动端浏览器并不是立即作出反应,而是会等上一小会儿才会出现点击的效果。
-
点击穿透;假如页面上有两个元素A和B。B元素在A元素之上。我们在B元素的 touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了click事件。这是因为在移动端浏览器,事件执行的顺序是touchstart touchend click.而click事件有300ms 的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转。
20.300ms延迟解决方案︰
-
方案一:禁用缩放
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1"> -
方案二:更改默认的视口窗口
<meta name="viewport" content="width=device-width">
-
(1)只用touch。(2)只用click。(3)tap延迟350ms再隐藏mask。(4) pointer-events
21.call & apply,两者之间的区别?
-
call和 apply都是改变this指向的方法,区别在于call可以写多个参数,而 apply只能写两个参数,第二个参数是一个数组,用于存放要传的参数。
22.sass和less有什么区别?
-
编译环境不一样Sass 的安装需要Ruby环境,是在服务端处理的,而Less是需要引人l less.js 来处理Less代码输出css 到浏览器,也可以在开发环节使用Less,然后编译成css文件,直接放到项目中。
-
变量符不一相,less是@,而scss是$,而且它们的作用域也不―样, less是块级作用域。
-
输出设置,Less没有输出设置,sass提供4种输出选项,nested,compact,compressed和expanded nested:嵌套缩进的css 代码(默认)expanded:展开的多行css 代码compact:简洁格式的css 代码compressed:压缩后的css 代码。
-
sass支持条件语句,可以使用if{elset,for科循环等等,而less不行。
-
引用外部css文件,sass 引用外部文件必须以开头,文件名如果以下划线形状,sass会认为该文件是一个引用文件,不会将其编译为css文件。less 引用外部文件和css 中的@import没什么差异。
23.bootstrap好处?
自适应和响应式布局,12栅格系统,统一的界面风格和css 样式有利于团队开发。编写灵活、稳定、高质量的 HTML和CSS代码的规范。
24.如何copy 一个dom元素?
原生Js 方法: var div = document.getElementsByTagName('div')[O];var clone div.cloneNode0;
Jquery方法: $(div').clone();
在默认情况下,.clone(方法不会复制匹配的元素或其后代元素中绑定的事件。不过,可以为这个方法传递一个布尔值参数,将这个参数设置为true,就可以连同事件一起复制,即.clone(true).
25.数组的排序方法(sort)?排序?汉字排序?
数组的排序方法: reverse()和sort()。reverse()方法会对反转数组项的顺序。Eg:vat values = [0,1,5,10,15]; values.sort();//10,1,10,15,5
var values = [1,2,3,4,5]; values.reverse();//5,4,3,2,1
26.commonjs?requirejs?AMDICMD|UMD?
-
CommonJS就是为JS的表现来制定规范,NodeJS是这种规范的实现,webpack 也是以CommonJS的形式来书写。因为js没有模块的功能,所以CommonJS应运而生。但它不能在浏览器中运行。CommonJS定义的模块分为{模块引用(require)} {模块定义(exports)}{模块标识(module)}
-
RequireJS是一个 JavaScript模块加载器。RequireJS有两个主要方法(method): define()和require().这两个方法基本上拥有相同的定义(declaration)并且它们都知道如何加载的依赖关系,然后执行一个回调函数(callback function).与require()不同的是,define()用来存储代码作为一个已命名的模块。因此define()的回调函数需要有一个返回值作为这个模块定义。这些类似被定义的模块叫作AMD (Asynchronous Module Definition,异步模块定义)。
-
AMD是RequireJS在推广过程中对模块定义的规范化产出 AMD异步加载模块。它的模块支持对象函数构造器字符串JSON等各种类型的模块。适用AMD规范适用define方法定义模块。
-
CMD是SeaJS在推广过程中对模块定义的规范化产出.。
27.js的几种继承方式?
-
使用对象冒充实现继承。
-
采用call、 Apply方法改变函数上下文实现继承。
-
原型链方式继承。
28.null,undefined 的区别?
undefined表示变量声明但未初始化的值,null表示准备用来保存对象,还没有真正保存对象的值。从逻辑角度看,null表示一个空对象指针。
29.ajax的缺点
-
ajax不支持浏览器back 按钮。
-
安全问题AAX暴露了与服务器交互的细节。
-
对搜索引擎的支持比较弱。
-
破坏了程序的异常机制。
-
不容易调试。
30.&&运算符能做什么
&&也可以叫逻辑与,在其操作数中找到第一个虚值表达式并返回它,如果没有找到任何虚值表达式,则返回最后一个真值表达式。它采用短路来防止不必要的工作。
31.event.preventDefault()和event.stopPropagation()方法之间有什么区别?
-
event.preventDefault()方法可防止元素的默认行为。如果在表单元素中使用,它将阻止其提交。如果在锚元素中使用,它将阻止其导航。如果在上下文菜单中使用,它将阻止其显示或显示。event.stopPropagation()方法用于阻止捕获和冒泡阶段中当前事件的进―步传播。
32.如何知道是否在元素中使用了event.preventDefaulto方法?
我们可以在事件对象中使用event.defaultPrevented 属性。它返回一个布尔值用来表明是否在特定元素中调用了event.preventDefault()。
33.什么是event.target ?
-
event.target,是发生事件的元素或触发事件的元素。
34.什么是event.currentTarget? ?
-
event.currentTarget是我们在其上显式附加事件处理程序的元素。
36.'use strict’是干嘛用的?
"use strict”是 ES5特性,它使我们的代码在函数或整个脚本中处于严格模式。严格模式帮助我们在代码的早期避免bug,并为其添加限制。
严格模式的一些限制∶
-
变量必须声明后再使用。
-
函数的参数不能有同名属性,否则报错。
-
不能使用with语句。
-
不能对只读属性赋值,否则报错。
-
不能使用前缀0表示八进制数,否则报错。
-
不能删除不可删除的属性,否则报错。
-
不能删除变量delete prop,会报错,只能删除属性delete global[prop]。
-
eval不能在它的外层作用域引入变量。
-
eval和arguments不能被重新赋值。
-
arguments不会自动反映函数参数的变化。
-
不能使用arguments.callee。
-
不能使用arguments.caller。
-
禁止this指向全局对象。
-
不能使用fn.caller和 fn.arguments获取函数调用的堆栈。
-
增加了保留字(比如protected、 static 和interface)。
37.Function.prototype.apply方法的用途是什么?
apply()方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
const details = {
message: "Hello World!"
};
function getMessage(){return this.message;}
getMessage.apply(details); // 'Hello World!'
38.Function.prototype.call方法的用途是什么?
call()方法使用一个指定的 this值和单独给出的一个或多个参数来调用一个函数。
const details = {message: 'Hello World!'};
function getMessageo(){
return this.message;
}
getMessage.call(details);// 'Hello World!'
39.Function.prototype.bind的用途是什么?
bind()方法创建一个新的函数,在 bind()被调用时,这个新函数的 this被指定为bind()的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
40.手动实现Array.prototype.map方法
map()方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
function map(arr, mapCallback){
//首先,检查传递的参数是否正确。
if (!Array.isArray(arr) ]|| !arr.length |l typeof mapCallback !== 'function'){
return[]
}else{
let result =[];
for (let i = 0, len = arr.length; i < len; i++){
result.push(mapCallback(arr[i], i, arr));
//将 mapCallback返回的结果push 到result数组中
}
return result;
}
41.如何创建一个没有prototype(原型)的对象?
我们可以使用Object.create方法创建没有原型的对象。
42.ES6或ECMAScript 2015有哪些新特性?
-
箭头函数。
-
类。
-
模板字符产。
-
加强的对象字面。
-
对象解构。
-
Promise
-
生成器
-
模块
-
Symbol
-
代理
-
Set
-
函数默认函数
-
rest和展开
-
块作用域
43.var,let和const的区别是什么?
-
var声明的变量会挂载在window 上,而let和 const声明的变量不会;
var a = 100;
console.log(a,window.a);// 100 100
let b = 10;
console.log(b,window.b);l/ 10 undefined
const c = 1;
console.log(c,window.c);// 1 undefined
-
var声明变量存在变量提升, let和const不存在变量提升.
-
同―作用域下 let和const不能声明同名变量,而var可以.
-
暂存死区:let和const会产生暂缓死区,控制台报错:Error:a is not defined。
44.什么是箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的 this , arguments,super 或 new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
45.什么是类?
类(class)是在'JS中编写构造函数的新方法。它是使用构造函数的语法糖,在底层中使用仍然是原型和基于原型的继承。
46.什么是对象解构?
对象析构是从对象或数组中获取或提取值的一种新的、更简洁的方法。假设有如下的对象︰
const employee = {
firstName: " Marko",
lastName: "Polo",
position: "Software Developer",
yearHired: 2017
}
从对象获取属性,早期方法是创建一个与对象属性同名的变量,这种方法很麻烦,因为我们要为每个属性创建一个新变量。假设我们有一个大对象,它有很多属性和方法,用这种方法提取属性会很麻烦。
使用解构方式语法就变得简洁多了:
{ firstName, lastName, position,yearHired } = employee;
let { firstName: fName, lastName:IName, position, yearHired} = employee;
47.什么是ES6模块?
模块使我们能够将代码基础分割成多个文件,以获得更高的可维护性,并且避免将所有代码放在一个大文件中。在 ES6支持模块之前,有两个流行的模块。
exports.isNull = function (val) {return val === null;}
export function isNull(val){return val === null;}
48.什么是set对象,它是如何工作的?
Set对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
const set1 =new Set();
const set2 = newset(["a","b","c" ,"d" , " d","e"]);
49.什么是async/await及其如何工作?
async/await是JS中编写异步或非阻塞代码的新方法。它建立在Promises 之上,让异步代码的可读性和简洁度都更高。
async/await是JS中编写异步或非阻塞代码的新方法。它建立在 Promises.之上,相对于Promise 和回调,它的可读性和简洁度都更高。但是,在便用此功能之前,我们必须先学习Promises 的基础知识,因为正如我之前所说,它是基于Promise构建的,这意味着幕后使用仍然是Promise.
使用Promise:
function callApi(){
return fetch("url/to/api/endpoint").then(resp => resp.json()).then(data=>{}).catch(err=>{})
}
使用在async/await
async function callApi() {
try {
} catch(e){
}
}
50.展开(spread)运算符和剩余(Rest)运算符有什么区别?
-
展开运算符(spread)是三个点(..),可以将一个数组转为用逗号分隔的参数序列。说的通俗易懂点,有点像化骨绵掌,把一个大元素给打散成一个个单独的小元素。
51.什么是包装对象(wrapper object) ?
-
原因是基本类型的值被临时转换或强制转换为对象,因此 name变量的行为类似于对象。除 null和undefined 之外的每个基本类型都有自己包装对象。也就是:string,Number,Boolean,Symbol和 Biglnt。在这种情况下,name.toupperCase()在幕后看起来如下:console.log(new String(name).toUpperCase());//"MARKO"。
52.隐式和显式转换有什么区别)?
-
隐式强制转换是一种将值转换为另一种类型的方法,这个过程是自动完成的,无需我们手动操作。类似:console.log('1'+6)
-
显式转换需要console.log(parseInt('1')+6)
53.什么是NaN?以及如何检查值是否为NaN?
NaN表示“非数字”是JS中的一个值,该值是将数字转换或执行为非数字值的运算结里,天比结果为NaN。
54.如何判断值是否为数组?
我们可以使用Array.isArray方法来检查值是否为数组。当传递给它的参数是数组时,它返回true,否则返回false。
55.in运算符和object.hasownProperty方法有什么区别?
-
hasOwnPropert()方法返回值是一个布尔值,指示对象自身属性中是否具有指定的属性,因此这个方法会忽略掉那些从原型链上继承到的属性。
-
in运算符:如果指定的属性在指定的对象或其原型链中,则in运算符返回true。列子:console.log('phone' in obj) 为true
56.有哪些方法可以处理JS中的异步代码?
-
回调
-
promise
-
async/await
57.调用函数,可以使用哪些方法?
在js中有4种方法可以调用
-
作为函数调用——如果―个函数没有作为方法、构造函数、 apply.call 调用时,此时this 指向的是window对象(非严格模式)
-
作为方法调用
-
作为构造函数调用
-
使用apply和call方法调用
const obj1 = {result:0}
const obj2 = {result:O}
function reduceAdd(){
let result = O;
for(let i = 0, len = arguments.length; i < len; i++){
result += arguments[i];
}
}
reduceAdd.apply(obj1,[1,2,3,4,5]);// reduceAdd函数中的this对象将是 obj1
_)
const obj1 = {
result:0);
const obj2 = {result:O
)};
function reduceAddO{let result = O;
for(let i = 0, len = arguments.length; i < len; i++){result += arguments[i];
}
this.result = result;}
reduceAdd.apply(obj1,[1,2,3,4,5]);l/ reduceAdd函数中的this对象将是 obj1
reduceAdd.call(obj2,1,2,3,4,5);// reduceAdd函数中的this 对象将是obj2
58.为什么typeof null返回object?如何检查一个值是否为null?
typeof null == 'object'总是返回true,因为这是自JS 诞生以来 null的实现。曾经有人提出将typeof null == 'object'修改为typeof null == 'null' ,但是被拒绝了,因为这将导致更多的bug。
59.new关键字有什么作用?
function Employee(name, position, yearHired) {
this.name = name;
this.position = position;
this.yearHired = yearHired;
}
const emp = new Employee("Marko Polo", "Software Developer", 2017);
new关键字做了4件事:
-
创建空对象{}
-
将空对象分配给this值
-
将空对象的_proto__指向构造函数的prototype
-
如果没有使用显式return语句,则返回this