1.如何把一句英文每个单词第一个字母大写?
var str = "what fuck is 1235 going on ?"; var newArr = str.split(" "); for(var i=0,myArr=[];i<newArr.length;i++){ myArr.push(newArr[i].replace(newArr[i].charAt(0),newArr[i].charAt(0).toUpperCase())); } console.log(myArr); var myStr=myArr.join(" "); console.log(myStr);
2.JS随机获取颜色的程序
<body> <div id="box"> </div> <button id="button">获取颜色</button> </body>
3.截取url参数
$(function() { var search=location.search;//获得路径 var params={};//定义一个空对象 if(params!=''){ var ps=search.slice(1).split('&');//截取?之后的路径,并以&切割 for(var i=0;i<ps.length;i++){//遍历参数数组 var arr=ps[i].split('=');//将数组每个元素以=切割 params[arr[0]]=arr[1];// } } var userId=params.userId; });
4.点击一个ul的五个li元素,分别弹出他们的序号
方法一:
<script> //设置index保存 var oLi=document.getElementsByTagName('li'); for(var i=0;i<oLi.length;i++){ oLi[i].index=i; oLi[i].onclick=function(){ alert(this.index); } } </script>
方法二: <script> var oLi=document.getElementsByTagName('li'); for(var i=0; i<oLi.length; i++){ (function(j){ oLi[j].onclick = function(){ alert(j); }; })(i); }
</script>
5.js数组去重
<script> //方法一:indexof查找 var arr=new Array(1,2,2,2,3,3,5,6,8,8,9); Array.prototype.unique1=function(){ var n=[]; for(var i=0;i<arr.length;i++){ if(n.indexOf(arr[i])==-1){ n.push(arr[i]); } } return n; } alert(arr.unique1()); </script> <script> //方法二:hash var arr=new Array(1,2,2,2,3,3,5,6,8,8,9); Array.prototype.unique2=function(){ var hash={},//hash表 n=[];//临时数组 for(var i=0;i<this.length;i++){ if(!hash[this[i]]){ //如果hash表中没有当前项 hash[this[i]]=true;//存入hash表 n.push(this[i]);//当前元素push到临时数组中 } } return n; } alert(arr.unique1()); </script>
6.js编程找出一段字符串中出现次数最多的字符以及出现的次数
var str="we are friends"; var maxLen=0; var index=""; var hash={}; for(var i=0;i<str.length;i++){ if(!hash[str.charAt(i)]){ hash[str.charAt(i)]=1; }else{ hash[str.charAt(i)]++; } } for(var i in hash){ if(hash[i]>maxLen){ maxLen=hash[i]; index=i; } } alert("出现次数最多的元素是:"+index+" 出现次数:"+maxLen);
7.js去掉字符串前后所有的空格
function Trim(str){ return str.replace(/(^s*)|(s*$)/g, ""); }
8.求一个字符串的字节长度
function getLen(str){ var len=0; for(var i=0;i<str.length;i++){ if(str.charCodeAt(i)>255){//charCodeAt() 方法可返回指定位置的字符的 Unicode 编码 len+=2; }else{ len++; } } return len; }
9.变量的坑
d(); e(); function d(){//用声明的方式声明的函数 alert('hello');//hello } var e = function(){//函数表达式 alert('world');//e is not a function }
10.冒泡排序
function arrSort(arr){ var len=arr.length; var nu = ''; for(var i=0;i<=len-1;i++){ for(var j=0;j<=len-1-i;j++){ if(arr[j]>arr[j+1]){ nu=arr[j]; arr[j]=arr[j+1]; arr[j+1]=nu; } } } return arr; }
11.实现距离某一天还有多久?
function getDay(){ var start = new Date(); var end = new Date(start.getFullYear()+1,'0'); var leftTime = (end.getTime()-start.getTime())/1000;//转成秒 var second = Math.floor(leftTime%60);//取余 var minute = Math.floor((leftTime/60))%60; var hour = Math.floor((leftTime/(60*60)))%24; var day = Math.floor((leftTime/(60*60*24)))%30; var month = Math.floor((leftTime/(60*60*24*30)))%12; return '距离明年还剩'+month+'月,'+day+'天,'+hour+'小时,'+minute+'分钟,'+second+'秒'; } setInterval(function(){ var text=getDay(); document.getElementById('time').innerHTML=text; },1000);
12.jquery 中如何将数组转化为json字符串,然后再转化回来?
jQuery中没有提供这个功能,所以你需要先编写两个jQuery的扩展:
$.fn.stringifyArray = function(array) {
return JSON.stringify(array)
}
$.fn.parseArray = function(array) {
return JSON.parse(array)
}
然后调用:
$("").stringifyArray(array)
13.非编程题
(1) [ ]==[ ]
答案:false.
数组,在 Javascript 中是对象,对象使用 == 比较都是比较的引用。
简单的说,就是,如果是同一个对象,就相等,如果不是同一个对象,就不等。
每次使用 [] 都是新建一个数组对象,所以 [] == [] 这个语句里建了两个数据对象,它们不等。
(2)Array.isArray(Array.prototype)
答案:true
Array.prototype为[],Array.isArray(a)是一个判断a是否为数组的方法。
(3)声明提前
var word="hello word";
(function(){
alert(word); //undefined
var word="hello test";
})();
谈话面试:
1、前端跨域你是如何处理的?如何处理安全性问题(劫持)?
2、关于JavaScript中this的详细总结?
解:1.全局上下文:无论是否在严格模式下,在全局执行上下文中(在任何函数体外部)this
都指代全局对象。【在全局执行上下文中 this
都是全局对象 window
】(浏览器环境)
2.函数上下文:在函数内部,this
的值取决于函数被调用的方式。【取决于被调用的方式】
3.bind方法:ECMAScript 5
引入了 Function.prototype.bind
。调用 f.bind(someObject)
会 创建一个与 f
具有相同函数体和作用域的函数,但是在这个新函数中,this
将永久地被绑定到了 bind
的第一个参数,无论这个函数是如何被调用的。
4.箭头函数:在箭头函数中,this
与封闭词法上下文的 this
保持一致。在全局代码中,它将被设置为全局对象
5.作为对象的方法:当函数作为对象里的方法被调用时,它们的 this
是调用该函数的对象
6.原型链中的this:对于在对象原型链上某处定义的方法,同样的概念也适用。如果该方法存在于一个对象的原型链上,那么 this
指向的是调用这个方法的对象,就像该方法在对象上一样。
7.作为构造函数:当一个函数用作构造函数时(适用 new
关键字),它的 this
被绑定到正在构造的新对象。虽然构造器返回的默认值是 this
所指的那个对象,但它仍可以手动返回其他的对象(如果返回值不是一个对象,则返回 this
对象)
8.作为DOM事件的处理函数:当函数被用作事件处理函数时,它的 this
指向触发事件的元素(一些浏览器在使用非 addEventListener
的函数动态添加监听函数时不遵守这个约定)
9.作为一个内敛事件处理函数:当代码被内联 on-event
处理函数 调用时,它的 this
指向监听器所在的 DOM
元素
3.理解JavaScipt中的深拷贝和浅拷贝?
解:需要先理解基本类型和引用类型:
ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置。而引用类型值是指那些保存堆内存中的对象,意思是变量中保存的实际只是这个对象的引用,这个引用指向堆内存中的对象。
目前基本类型有:Boolean、Null、Undefined、Number、String、Symbol。
引用类型有:Object、Array、Function。
深拷贝与浅拷贝的概念只存在于引用类型。
浅拷贝:
var obj1 = {x:1, y:2},obj2 = obj1; console.log(obj1) // {x:1, y:2} console.log(obj2) // {x:1, y:2} obj2.x = 2; // 修改obj2.x console.log(obj1) // {x:2, y:2} console.log(obj2) // {x:2, y:2}
深拷贝:
数组:slice()只能实现一维数组的深拷贝,Object.assign()也只能实现一维对象的深拷贝。 var arr1 = [1, 2], arr2 = arr1.slice(); console.log(arr1); //[1, 2] console.log(arr2); //[1, 2] arr2[0] = 3; //修改arr2 console.log(arr1); //[1, 2] console.log(arr2); //[3, 2]
4.既然localStorage和sessionStorage能做到数据维护,为什么还要引入vuex?
解:可维护性:因为是单向数据流,所有状态是有迹可循的,数据的传递也可以及时分发响应
易用性:它使得我们组件间的通讯变得更强大,而不用借助中间件这类来实现不同组件间的通讯
而且代码量不多,若是你要用 localStorage
或者 sessionStorage
,你必须手动去跟踪维护你的状态表,虽说可行,但是代码量会多很多,而且可读性很差
5、vuex的用户信息为什么还要载存一遍到浏览器里(localStorage
,sessionStorage
)?
解:因为 vuex
的 store 干不过刷新啊
保存在浏览器的缓存内,若用户刷新的话,值再取一遍呗。
3、什么是jsonp?
解:浏览器在请求不同域的资源时,会因为同源策略的影响请求不成功,这就是通常被提到的“跨域问题”。
同源策略",即同域名(domain或ip)、同端口、同协议的才能互相获取资源,而不能访问其他域的资源。在同源策略影响下,一个域名A的网页可以获取域名B下的脚本,css,图片等,但是不能发送Ajax请求,也不能操作Cookie、LocalStorage等数据。同源策略的存在,一方面提高了网站的安全性,但同时在面对前后端分离、模拟测试等场景时,也带来了一些麻烦,从而不得不寻求一些方法来突破限制,获取资源。
4、vue父子组件如何进行通讯?
解:父组件传数据给子组件,通过props属性来实现
<parent> <child :child-msg="msg"></child>//这里必须要用 - 代替驼峰 </parent> data(){ return { msg: [1,2,3] }; }
方法一:
props: ['childMsg']
方法二:
props: {
childMsg: Array //这样可以指定传入的类型,如果类型不对,会警告
}
方法三:
props: { childMsg: { type: Array, default: [0,0,0] //这样可以指定默认的值 } }
如果子组件想要改变数据呢?这在vue中是不允许的,因为vue只允许单向数据传递,这时候我们可以通过触发事件来通知父组件改变数据,从而达到改变子组件数据的目的.emit
子组件: <template> <div @click="up"></div> </template> methods: { up() { this.$emit('upup','hehe'); //主动触发upup方法,'hehe'为向父组件传递的数据 } }
父组件: <div> <child @upup="change" :msg="msg"></child> //监听子组件触发的upup事件,然后调用change方法 </div> methods: { change(msg) { this.msg = msg; } }
5、vue多个父子组件如何进行通讯?
vue的生命周期钩子
每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们自己的代码。
beforeCreate: //创建之前:vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。
created: //创建完毕:vue实例的数据对象data有了,$el还没有
beforeMount: //挂载前,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的DOM节点,data.message还未替换。
mounted: // 挂载完毕,data.message成功渲染。
beforeUpdate: // 修改vue实例的data时,vue会自动更新渲染视图
beforeDestroy: // 销毁之前
destroyed: // 销毁成功
深入响应式原理
当你把一个普通的javascript对象传给vue实例的data选项,vue将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter
这些getter/setter对用户来说是不可见的,但是在内部他们让vue追踪依赖,在属性被访问和修改时通知变化。这里需要注意的问题是浏览器控制台在打印数据对象时getter/setter的格式化并不同,所以需要安装vue-devtools来获取更加友好的检查接口。
每个组件实例都有相应的watcher实例对象,他会在组件渲染的过程中把属性记录为依赖,之后当依赖的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。
⦁ Vue中实现了数据的双向绑定,为了支持双向绑定,就必须时刻追踪数据变化并及时响应到ui上。
⦁ Vue通过Object.defineProperty()设置对象的存储器属性,并对对象中的每个值,重写了其中的get、set,data中的每个key,都有一个独立的依赖收集器。
⦁ 在get中,向依赖收集器添加了监听
⦁ 在mount时,实例了一个Watcher,将收集器的目标指向了当前Watcher
⦁ 在data值发生变更时,触发set,触发了依赖收集器中的所有监听的更新,来触发Watcher.update
Vue中的MVVM模式
vue是以数据驱动的,vue本身将Dom和数据进行绑定,一旦创建绑定,DOM和数据将保持同步,每当数据发生变化,DOM会跟着变化。ViewModel是vue的核心,它是vue的一个实例。
Vue中的状态管理
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
computed和watch的区别
计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算
监听某一个值,当被监听的值发生变化时,执行对应的操作
与computed的区别是,watch更加适用于监听某一个值的变化并做对应的操作,比如请求后台接口等,而computed适用于计算已有的值并返回结果
6、什么是事件代理?
解:javaScript的事件代理也叫事件委托。
比如我们有100个li,每个li都有相同的click点击事件,可能我们会用for循环的方法,来遍历所有的li,然后给它们添加事件,
通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,
代理呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。
就是利用事件冒泡的原理,把事件加到父级元素上,触发执行效果。从而可以很大程度上来提高执行的效率、而且就算新添加了元素还是会有代理的事件
7、javascript代理模式你知道吗?
8、call 和 apply 、箭头函数 在什么场景下使用,他们的作用是什么?
解:相同,call和apply,专门用于借用一个函数,并替换函数中的this为指定对象。
不同,call要求传入函数的参数必须独立传入。
apply要求传入函数的参数必须放入一个数组或集合中,整体传入。
9.请描述一下cookies,sessionStorage和localStorage的区别?
解:web存储,在开发web应用时,开发人员有时需要在本地存储数据,当前浏览器支持cookie存储,但其大小有4KB限制。
html5中的web存储对象有两种类型:
sessionStorage对象,负责存储一个会话的数据。如果用户关闭了页面或浏览器,则会销毁数据,一次会话结束,存储的信息会自动删除,
存储的数据无法垮页面存在,只在当前页面。
localStorage对象,负责存储没有到期的数据,当web页面或浏览器关闭时,仍会保持数据的存储,当然这还取决于为此用户的浏览器设置
的存储量,如果不是人为删除,存储的信息会一直保留,存储的数据内容是可以跨页的。
10.移动页面专题如何适配不同分辨率(保持整个页面等比例一致)
解:设置width=device-width,然后用百分比来分配屏幕宽度,高度自适应变化,字体也使用相对大小em,rem等等
11.移动端点击穿透的原因是什么?怎么解决?
原因:click与300ms延迟
移动浏览器提供一个特殊的功能:双击(double tap)放大
300ms的延迟就来自这里,用户碰触页面之后,需要等待一段时间来判断是不是双击(double tap)动作,而不是立即响应单击(click),等待的这段时间大约是300ms。
a、不要混用touch和click
既然touch之后300ms会触发click,只用touch或者只用click就自然不会存在问题了
12.什么是原型链?写一段原型链代码?
在javaScript中一切皆对象,但是对象又分为函数对象和普通对象,通过new出来的都是函数对象,function是默认的函数对象,函数对象有一个默认的属性prototype,指向原型对象。原型对象上的方法和属性,可以被这个函数创建的实例引用。
this.name = 'John'; } Person.prototype = { say: function() { console.log('Hello,' + this.name); } }; var person = new Person(); person.say();//person.say is not a function//函数B想要使用函数A的变量
functionSuper(){
this
.val = 1;
this
.arr = [1];
}
function
Sub(){
// ...
}
Sub.prototype =
new
Super();
// 核心
var
sub1 =
new
Sub();
var
sub2 =
new
Sub();
sub1.val = 2;
sub1.arr.push(2);
alert(sub1.val);
// 2
alert(sub2.val);
// 1
alert(sub1.arr);
// 1, 2
alert(sub2.arr);
// 1, 2
13.前端如何压缩用户上传的图片?
上传前用js对图片压缩,把利用canvas生成的base64字符串,传入后台, * (无所谓ajax或者form,同时也可以解决图片无刷新上传), * 在Java后台将获取到的base64字符串输出为图片,即可。
14.手机上拍照为什么有时候会得到旋转90度的照片?怎么解决?
解:其实是拿手机拍照的方向问题,iphone正确的手机拍照方式是横屏的,用户往往是竖屏拍照等于照相机反转了90度,出来的照片当然是反转90度,当你横屏拍照上传,图片就是正确的,一张生成的图片是无法辨别选择方向的,只有在上传前反转角度才行。
//获取图片方向 function getPhotoOrientation(img) { var orient; EXIF.getData(img, function () { orient = EXIF.getTag(this, 'Orientation'); }); return orient; }
//图片压缩 function compress(img, width, height, ratio) { var canvas, ctx, img64, orient; //获取图片方向 orient = getPhotoOrientation(img); canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; ctx = canvas.getContext("2d"); //如果图片方向等于6 ,则旋转矫正,反之则不做处理 if (orient == 6) { ctx.save(); ctx.translate(width / 2, height / 2); ctx.rotate(90 * Math.PI / 180); ctx.drawImage(img, 0 - height / 2, 0 - width / 2, height, width); ctx.restore(); } else { ctx.drawImage(img, 0, 0, width, height); } img64 = canvas.toDataURL("image/jpeg", ratio); return img64; }
15.什么是前端路由?什么时候适合使用前端路由?前端路由有哪些优点和缺点?
解:路由是根据不同的 url 地址展示不同的内容或页面
前端路由更多用在单页应用上, 也就是SPA, 因为单页应用, 基本上都是前后端分离的, 后端自然也就不会给前端提供路由。
优点:
1.从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升。
2.在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户就不能复制到想要的地址,用前端路由做单页面网页就很好的解决了这个问题
缺点:
使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。
16.请讲解一下闭包?
解:包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
使用闭包的注意点:
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
17.js中的作用域和作用域链
作用域指变量和函数的可使用范围,在JavaScript中变量的作用域分为局部作用域和全局作用域。1.全局作用域
(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域
(2)所有末定义直接赋值的变量自动声明为拥有全局作用域。
(3)所有window对象的属性拥有全局作用域
2.局部作用域
函数内部声明的变量。
3.作用域链
程序执行的时候会创建一个执行环境栈,首先将window的执行环境压入到执行环境栈中,window是全局的,里面存放全局的变量和函数。
当调用一个函数的时候,会将这个函数的执行环境压入到执行环境栈中,并且还会创建这个函数的活动对象,指向活动对象。活动对象中保存
函数内部的变量也就是局部变量,活动对象指向window。
函数调用完之后,它的执行环境会被释放,它指向的活动对象也会被释放。活动对象中保存的局部变量也被释放。当查找一个变量时,首先去
活动对象中查找,找不到就沿着作用域链向下查找,如果window中都找不到,就会报错。格局作用于逐级引用形成作用域链。
18.同步和异步
同步就是指一个进程在执行某个请求的时候,若该请求需要隔一段时间才能返回信息,那么这个进程会一直等待下去,直到收到返回消息才会继续执行下去
异步请求是指进程不需要一直等待下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时,系统会通知进程进行处理,这样可以提高执行效率。
setTimeout(function cbFn(){ console.log('learnInPro'); }, 1000); console.log('sync things');
setTimeout就是一个异步任务
,当JS引擎顺序执行到setTimeout的时候发现他是个异步任务,则会把这个任务挂起,继续执行后面的代码。直到1000ms后,回调函数cbFn才会执行,这就是异步,在执行到setTimeout的时候,JS并不会傻呵呵的等着1000ms执行cbFn回调函数,而是继续执行了后面的代码
为什么要在js中写异步?
由于javascript是单线程的,只能在JS引擎的主线程上运行的,所以js代码只能一行一行的执行,不能在同一时间执行多个js代码任务,这就导致如果有一段耗时较长的计算,或者是一个ajax请求等IO操作,如果没有异步的存在,就会出现用户长时间等待,并且由于当前任务还未完成,所以这时候所有的其他操作都会无响应。
11.http://blog.csdn.net/gaoshanwudi/article/details/7355794闭包
19.重载
argument。length判断参数的个数。
20.热加载
21.vue的缺点
22.不固定高宽div垂直居中的方法
<div class="block" style="height: 300px;"> <div class="centered"> <h1>haorooms案例题目</h1> <p>haorooms案例内容,haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容</p> </div> </div>
/* This parent can be any width and height */
.block {
text-align: center;
}
/* The ghost, nudged to maintain perfect centering */
.block:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
/* The element to be centered, can
also be of any width and height */
.centered {
display: inline-block;
vertical-align: middle;
width: 50%;
}
21.匿名函数和普通函数的区别?
普通函数可以在声明之前调用,
匿名函数会被当做普通表达式,存在声明提前。
a();
//a函数可以在它定义的前面调用
b();
//b函数这样调用就会出“未定义”错误
function
a()
{
alert(
"aaaaaa"
);
}
var
b =
function
()
{
alert(
"bbbbbb"
);
}
22. 网页从输入网址到渲染完成经历了哪些过程?
大致可以分为如下7步:
输入网址;
发送到DNS服务器,并获取域名对应的web服务器对应的ip地址;
与web服务器建立TCP连接;
浏览器向web服务器发送http请求;
web服务器响应请求,并返回指定url的数据(或错误信息,或重定向的新的url地址);
浏览器下载web服务器返回的数据及解析html源文件;
生成DOM树,解析css和js,渲染页面,直至显示完成;
23.jquey如何扩展自定义方法
(jQuery.fn.myMethod=function(){ alert('myMethod'); }) // 或者: (function($){ $.fn.extend({ myMethod: function(){ alert('myMethod') } }) })(jQuery)
// 使用
$("#div").myMethod();